diff options
Diffstat (limited to 'Source')
546 files changed, 14757 insertions, 13428 deletions
diff --git a/Source/.gitattributes b/Source/.gitattributes index 7c160cc..d0aedc2 100644 --- a/Source/.gitattributes +++ b/Source/.gitattributes @@ -1,2 +1,4 @@ +CMakeVersion.cmake export-subst + # Do not format third-party sources. /kwsys/** -format.clang-format-6.0 diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 695e075..7cd07a8 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -95,9 +95,6 @@ include_directories( ${CMake_HAIKU_INCLUDE_DIRS} ) -# let cmake know it is supposed to use it -add_definitions(-DCMAKE_BUILD_WITH_CMAKE) - # Check if we can build the ELF parser. if(CMAKE_USE_ELF_PARSER) set(ELF_SRCS cmELF.h cmELF.cxx) @@ -142,10 +139,33 @@ set(SRCS cmAffinity.cxx cmAffinity.h + cmAlgorithms.h cmArchiveWrite.cxx cmArgumentParser.cxx cmArgumentParser.h cmBase32.cxx + cmBinUtilsLinker.cxx + cmBinUtilsLinker.h + cmBinUtilsLinuxELFGetRuntimeDependenciesTool.cxx + cmBinUtilsLinuxELFGetRuntimeDependenciesTool.h + cmBinUtilsLinuxELFLinker.cxx + cmBinUtilsLinuxELFLinker.h + cmBinUtilsLinuxELFObjdumpGetRuntimeDependenciesTool.cxx + cmBinUtilsLinuxELFObjdumpGetRuntimeDependenciesTool.h + cmBinUtilsMacOSMachOGetRuntimeDependenciesTool.cxx + cmBinUtilsMacOSMachOGetRuntimeDependenciesTool.h + cmBinUtilsMacOSMachOLinker.cxx + cmBinUtilsMacOSMachOLinker.h + cmBinUtilsMacOSMachOOToolGetRuntimeDependenciesTool.cxx + cmBinUtilsMacOSMachOOToolGetRuntimeDependenciesTool.h + cmBinUtilsWindowsPEDumpbinGetRuntimeDependenciesTool.cxx + cmBinUtilsWindowsPEDumpbinGetRuntimeDependenciesTool.h + cmBinUtilsWindowsPEGetRuntimeDependenciesTool.cxx + cmBinUtilsWindowsPEGetRuntimeDependenciesTool.h + cmBinUtilsWindowsPELinker.cxx + cmBinUtilsWindowsPELinker.h + cmBinUtilsWindowsPEObjdumpGetRuntimeDependenciesTool.cxx + cmBinUtilsWindowsPEObjdumpGetRuntimeDependenciesTool.h cmCacheManager.cxx cmCacheManager.h cmCLocaleEnvironmentScope.h @@ -295,6 +315,10 @@ set(SRCS cmInstallTargetGenerator.cxx cmInstallDirectoryGenerator.h cmInstallDirectoryGenerator.cxx + cmLDConfigLDConfigTool.cxx + cmLDConfigLDConfigTool.h + cmLDConfigTool.cxx + cmLDConfigTool.h cmLinkedTree.h cmLinkItem.cxx cmLinkItem.h @@ -338,7 +362,6 @@ set(SRCS cmProcessOutput.h cmProcessTools.cxx cmProcessTools.h - cmProperty.cxx cmProperty.h cmPropertyDefinition.cxx cmPropertyDefinition.h @@ -360,6 +383,8 @@ set(SRCS cmQtAutoRcc.h cmRST.cxx cmRST.h + cmRuntimeDependencyArchive.cxx + cmRuntimeDependencyArchive.h cmScriptGenerator.h cmScriptGenerator.cxx cmSourceFile.cxx @@ -376,6 +401,8 @@ set(SRCS cmStateSnapshot.cxx cmStateSnapshot.h cmStateTypes.h + cmStringAlgorithms.cxx + cmStringAlgorithms.h cmSystemTools.cxx cmSystemTools.h cmTarget.cxx @@ -502,6 +529,8 @@ set(SRCS cmFindProgramCommand.h cmForEachCommand.cxx cmForEachCommand.h + cmFunctionBlocker.cxx + cmFunctionBlocker.h cmFunctionCommand.cxx cmFunctionCommand.h cmGetCMakePropertyCommand.cxx @@ -607,6 +636,8 @@ set(SRCS cmStringReplaceHelper.cxx cmStringCommand.cxx cmStringCommand.h + cmSubcommandTable.cxx + cmSubcommandTable.h cmSubdirCommand.cxx cmSubdirCommand.h cmSubdirDependsCommand.cxx @@ -635,8 +666,6 @@ set(SRCS cmTryCompileCommand.h cmTryRunCommand.cxx cmTryRunCommand.h - cmUnexpectedCommand.cxx - cmUnexpectedCommand.h cmUnsetCommand.cxx cmUnsetCommand.h cmUseMangledMesaCommand.cxx @@ -1134,6 +1163,21 @@ include (${CMake_BINARY_DIR}/Source/LocalUserOptions.cmake OPTIONAL) include (${CMake_SOURCE_DIR}/Source/LocalUserOptions.cmake OPTIONAL) if(WIN32) + # Compute the binary version that appears in the RC file. Version + # components in the RC file are 16-bit integers so we may have to + # split the patch component. + if(CMake_VERSION_PATCH MATCHES "^([0-9]+)([0-9][0-9][0-9][0-9])$") + set(CMake_RCVERSION_YEAR "${CMAKE_MATCH_1}") + set(CMake_RCVERSION_MONTH_DAY "${CMAKE_MATCH_2}") + string(REGEX REPLACE "^0+" "" CMake_RCVERSION_MONTH_DAY "${CMake_RCVERSION_MONTH_DAY}") + set(CMake_RCVERSION ${CMake_VERSION_MAJOR},${CMake_VERSION_MINOR},${CMake_RCVERSION_YEAR},${CMake_RCVERSION_MONTH_DAY}) + unset(CMake_RCVERSION_MONTH_DAY) + unset(CMake_RCVERSION_YEAR) + else() + set(CMake_RCVERSION ${CMake_VERSION_MAJOR},${CMake_VERSION_MINOR},${CMake_VERSION_PATCH}) + endif() + set(CMake_RCVERSION_STR ${CMake_VERSION}) + # Add Windows executable version information. configure_file("CMakeVersion.rc.in" "CMakeVersion.rc" @ONLY) diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index efbbeb4..ae9ce18 100644 --- a/Source/CMakeVersion.cmake +++ b/Source/CMakeVersion.cmake @@ -1,5 +1,82 @@ # CMake version number components. set(CMake_VERSION_MAJOR 3) set(CMake_VERSION_MINOR 15) -set(CMake_VERSION_PATCH 2) +set(CMake_VERSION_PATCH 20190828) #set(CMake_VERSION_RC 0) +set(CMake_VERSION_IS_DIRTY 0) + +# Start with the full version number used in tags. It has no dev info. +set(CMake_VERSION + "${CMake_VERSION_MAJOR}.${CMake_VERSION_MINOR}.${CMake_VERSION_PATCH}") +if(DEFINED CMake_VERSION_RC) + set(CMake_VERSION "${CMake_VERSION}-rc${CMake_VERSION_RC}") +endif() + +# Releases define a small patch level. +if("${CMake_VERSION_PATCH}" VERSION_LESS 20000000) + set(CMake_VERSION_IS_RELEASE 1) +else() + set(CMake_VERSION_IS_RELEASE 0) +endif() + +if(EXISTS ${CMake_SOURCE_DIR}/.git) + find_package(Git QUIET) + if(GIT_FOUND) + macro(_git) + execute_process( + COMMAND ${GIT_EXECUTABLE} ${ARGN} + WORKING_DIRECTORY ${CMake_SOURCE_DIR} + RESULT_VARIABLE _git_res + OUTPUT_VARIABLE _git_out OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_VARIABLE _git_err ERROR_STRIP_TRAILING_WHITESPACE + ) + endmacro() + endif() +endif() + +# Try to identify the current development source version. +if(COMMAND _git) + # Get the commit checked out in this work tree. + _git(log -n 1 HEAD "--pretty=format:%h %s" --) + set(git_info "${_git_out}") +else() + # Get the commit exported by 'git archive'. + set(git_info [==[$Format:%h %s$]==]) +endif() + +# Extract commit information if available. +if(git_info MATCHES "^([0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]?[0-9a-f]?)[0-9a-f]* (.*)$") + # Have commit information. + set(git_hash "${CMAKE_MATCH_1}") + set(git_subject "${CMAKE_MATCH_2}") + + # If this is not the exact commit of a release, add dev info. + if(NOT "${git_subject}" MATCHES "^[Cc][Mm]ake ${CMake_VERSION}$") + set(CMake_VERSION "${CMake_VERSION}-g${git_hash}") + endif() + + # If this is a work tree, check whether it is dirty. + if(COMMAND _git) + _git(update-index -q --refresh) + _git(diff-index --name-only HEAD --) + if(_git_out) + set(CMake_VERSION_IS_DIRTY 1) + endif() + endif() +else() + # No commit information. + if(NOT CMake_VERSION_IS_RELEASE) + # Generic development version. + set(CMake_VERSION "${CMake_VERSION}-git") + endif() +endif() + +# Extract the version suffix component. +if(CMake_VERSION MATCHES "-(.*)$") + set(CMake_VERSION_SUFFIX "${CMAKE_MATCH_1}") +else() + set(CMake_VERSION_SUFFIX "") +endif() +if(CMake_VERSION_IS_DIRTY) + set(CMake_VERSION ${CMake_VERSION}-dirty) +endif() diff --git a/Source/CMakeVersionCompute.cmake b/Source/CMakeVersionCompute.cmake deleted file mode 100644 index 72a5800..0000000 --- a/Source/CMakeVersionCompute.cmake +++ /dev/null @@ -1,44 +0,0 @@ -# Load version number components. -include(${CMake_SOURCE_DIR}/Source/CMakeVersion.cmake) - -# Releases define a small patch level. -if("${CMake_VERSION_PATCH}" VERSION_LESS 20000000) - set(CMake_VERSION_IS_DIRTY 0) - set(CMake_VERSION_IS_RELEASE 1) - set(CMake_VERSION_SOURCE "") -else() - set(CMake_VERSION_IS_DIRTY 0) # may be set to 1 by CMakeVersionSource - set(CMake_VERSION_IS_RELEASE 0) - include(${CMake_SOURCE_DIR}/Source/CMakeVersionSource.cmake) -endif() - -# Compute the full version string. -set(CMake_VERSION ${CMake_VERSION_MAJOR}.${CMake_VERSION_MINOR}.${CMake_VERSION_PATCH}) -if(CMake_VERSION_SOURCE) - set(CMake_VERSION_SUFFIX "${CMake_VERSION_SOURCE}") -elseif(CMake_VERSION_RC) - set(CMake_VERSION_SUFFIX "rc${CMake_VERSION_RC}") -else() - set(CMake_VERSION_SUFFIX "") -endif() -if(CMake_VERSION_SUFFIX) - set(CMake_VERSION ${CMake_VERSION}-${CMake_VERSION_SUFFIX}) -endif() -if(CMake_VERSION_IS_DIRTY) - set(CMake_VERSION ${CMake_VERSION}-dirty) -endif() - -# Compute the binary version that appears in the RC file. Version -# components in the RC file are 16-bit integers so we may have to -# split the patch component. -if(CMake_VERSION_PATCH MATCHES "^([0-9]+)([0-9][0-9][0-9][0-9])$") - set(CMake_RCVERSION_YEAR "${CMAKE_MATCH_1}") - set(CMake_RCVERSION_MONTH_DAY "${CMAKE_MATCH_2}") - string(REGEX REPLACE "^0+" "" CMake_RCVERSION_MONTH_DAY "${CMake_RCVERSION_MONTH_DAY}") - set(CMake_RCVERSION ${CMake_VERSION_MAJOR},${CMake_VERSION_MINOR},${CMake_RCVERSION_YEAR},${CMake_RCVERSION_MONTH_DAY}) - unset(CMake_RCVERSION_MONTH_DAY) - unset(CMake_RCVERSION_YEAR) -else() - set(CMake_RCVERSION ${CMake_VERSION_MAJOR},${CMake_VERSION_MINOR},${CMake_VERSION_PATCH}) -endif() -set(CMake_RCVERSION_STR ${CMake_VERSION}) diff --git a/Source/CMakeVersionSource.cmake b/Source/CMakeVersionSource.cmake deleted file mode 100644 index 5ea1de3..0000000 --- a/Source/CMakeVersionSource.cmake +++ /dev/null @@ -1,30 +0,0 @@ -# Try to identify the current development source version. -set(CMake_VERSION_SOURCE "") -if(EXISTS ${CMake_SOURCE_DIR}/.git/HEAD) - find_program(GIT_EXECUTABLE NAMES git git.cmd) - mark_as_advanced(GIT_EXECUTABLE) - if(GIT_EXECUTABLE) - execute_process( - COMMAND ${GIT_EXECUTABLE} rev-parse --verify -q --short=4 HEAD - OUTPUT_VARIABLE head - OUTPUT_STRIP_TRAILING_WHITESPACE - WORKING_DIRECTORY ${CMake_SOURCE_DIR} - ) - if(head) - set(CMake_VERSION_SOURCE "g${head}") - execute_process( - COMMAND ${GIT_EXECUTABLE} update-index -q --refresh - WORKING_DIRECTORY ${CMake_SOURCE_DIR} - ) - execute_process( - COMMAND ${GIT_EXECUTABLE} diff-index --name-only HEAD -- - OUTPUT_VARIABLE dirty - OUTPUT_STRIP_TRAILING_WHITESPACE - WORKING_DIRECTORY ${CMake_SOURCE_DIR} - ) - if(dirty) - set(CMake_VERSION_IS_DIRTY 1) - endif() - endif() - endif() -endif() diff --git a/Source/CPack/IFW/cmCPackIFWCommon.cxx b/Source/CPack/IFW/cmCPackIFWCommon.cxx index 1e72641..f9ce822 100644 --- a/Source/CPack/IFW/cmCPackIFWCommon.cxx +++ b/Source/CPack/IFW/cmCPackIFWCommon.cxx @@ -5,6 +5,7 @@ #include "cmCPackGenerator.h" #include "cmCPackIFWGenerator.h" #include "cmCPackLog.h" // IWYU pragma: keep +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmTimestamp.h" #include "cmVersionConfig.h" @@ -77,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; - cmSystemTools::ExpandListArgument(arg, args, false); + std::vector<std::string> args = cmExpandedList(arg, false); if (args.empty()) { return; } @@ -99,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; - cmSystemTools::ExpandListArgument(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 c1b6eea..8f13d0e 100644 --- a/Source/CPack/IFW/cmCPackIFWGenerator.cxx +++ b/Source/CPack/IFW/cmCPackIFWGenerator.cxx @@ -11,6 +11,7 @@ #include "cmCPackLog.h" // IWYU pragma: keep #include "cmDuration.h" #include "cmGeneratedFileStream.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include <sstream> @@ -34,8 +35,7 @@ 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()) { @@ -116,8 +116,8 @@ int cmCPackIFWGenerator::PackageFiles() // Run binary creator { - std::string ifwCmd = this->BinCreator; - ifwCmd += " -c " + this->toplevel + "/config/config.xml"; + std::string ifwCmd = + cmStrCat(this->BinCreator, " -c ", this->toplevel, "/config/config.xml"); if (!this->Installer.Resources.empty()) { ifwCmd += " -r "; @@ -253,7 +253,7 @@ int cmCPackIFWGenerator::InitializeInternal() // Look 'binarycreator' executable (needs) const char* BinCreatorStr = this->GetOption(BinCreatorOpt); - if (!BinCreatorStr || cmSystemTools::IsNOTFOUND(BinCreatorStr)) { + if (!BinCreatorStr || cmIsNOTFOUND(BinCreatorStr)) { this->BinCreator.clear(); } else { this->BinCreator = BinCreatorStr; @@ -270,7 +270,7 @@ int cmCPackIFWGenerator::InitializeInternal() // Look 'repogen' executable (optional) const char* RepoGenStr = this->GetOption(RepoGenOpt); - if (!RepoGenStr || cmSystemTools::IsNOTFOUND(RepoGenStr)) { + if (!RepoGenStr || cmIsNOTFOUND(RepoGenStr)) { this->RepoGen.clear(); } else { this->RepoGen = RepoGenStr; @@ -292,14 +292,14 @@ int cmCPackIFWGenerator::InitializeInternal() // Additional packages dirs this->PkgsDirsVector.clear(); if (const char* dirs = this->GetOption("CPACK_IFW_PACKAGES_DIRECTORIES")) { - cmSystemTools::ExpandListArgument(dirs, this->PkgsDirsVector); + cmExpandList(dirs, this->PkgsDirsVector); } // Additional repositories dirs this->RepoDirsVector.clear(); if (const char* dirs = this->GetOption("CPACK_IFW_REPOSITORIES_DIRECTORIES")) { - cmSystemTools::ExpandListArgument(dirs, this->RepoDirsVector); + cmExpandList(dirs, this->RepoDirsVector); } // Installer @@ -316,18 +316,17 @@ int cmCPackIFWGenerator::InitializeInternal() // Repositories if (const char* RepoAllStr = this->GetOption("CPACK_IFW_REPOSITORIES_ALL")) { - std::vector<std::string> RepoAllVector; - cmSystemTools::ExpandListArgument(RepoAllStr, RepoAllVector); + std::vector<std::string> RepoAllVector = cmExpandedList(RepoAllStr); for (std::string const& r : RepoAllVector) { this->GetRepository(r); } } if (const char* ifwDownloadAll = this->GetOption("CPACK_IFW_DOWNLOAD_ALL")) { - this->OnlineOnly = cmSystemTools::IsOn(ifwDownloadAll); + this->OnlineOnly = cmIsOn(ifwDownloadAll); } else if (const char* cpackDownloadAll = this->GetOption("CPACK_DOWNLOAD_ALL")) { - this->OnlineOnly = cmSystemTools::IsOn(cpackDownloadAll); + this->OnlineOnly = cmIsOn(cpackDownloadAll); } else { this->OnlineOnly = false; } diff --git a/Source/CPack/IFW/cmCPackIFWInstaller.cxx b/Source/CPack/IFW/cmCPackIFWInstaller.cxx index a075a17..b4bfea7 100644 --- a/Source/CPack/IFW/cmCPackIFWInstaller.cxx +++ b/Source/CPack/IFW/cmCPackIFWInstaller.cxx @@ -8,6 +8,7 @@ #include "cmCPackIFWRepository.h" #include "cmCPackLog.h" // IWYU pragma: keep #include "cmGeneratedFileStream.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmXMLParser.h" #include "cmXMLWriter.h" @@ -192,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"; } @@ -244,8 +245,7 @@ void cmCPackIFWInstaller::ConfigureFromOptions() if (const char* optIFW_PACKAGE_RESOURCES = this->GetOption("CPACK_IFW_PACKAGE_RESOURCES")) { this->Resources.clear(); - cmSystemTools::ExpandListArgument(optIFW_PACKAGE_RESOURCES, - this->Resources); + cmExpandList(optIFW_PACKAGE_RESOURCES, this->Resources); } } @@ -292,7 +292,7 @@ protected: { if (this->file) { std::string content(data, data + length); - content = cmSystemTools::TrimWhitespace(content); + content = cmTrimWhitespace(content); std::string source = this->basePath + "/" + content; std::string destination = this->path + "/" + content; if (!cmSystemTools::CopyFileIfDifferent(source, destination)) { diff --git a/Source/CPack/IFW/cmCPackIFWPackage.cxx b/Source/CPack/IFW/cmCPackIFWPackage.cxx index a1a52b1..fb75145 100644 --- a/Source/CPack/IFW/cmCPackIFWPackage.cxx +++ b/Source/CPack/IFW/cmCPackIFWPackage.cxx @@ -8,6 +8,7 @@ #include "cmCPackIFWInstaller.h" #include "cmCPackLog.h" // IWYU pragma: keep #include "cmGeneratedFileStream.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmTimestamp.h" #include "cmXMLWriter.h" @@ -196,7 +197,7 @@ int cmCPackIFWPackage::ConfigureFromComponent(cmCPackComponent* component) // User interfaces if (const char* option = this->GetOption(prefix + "USER_INTERFACES")) { this->UserInterfaces.clear(); - cmSystemTools::ExpandListArgument(option, this->UserInterfaces); + cmExpandList(option, this->UserInterfaces); } // CMake dependencies @@ -209,7 +210,7 @@ int cmCPackIFWPackage::ConfigureFromComponent(cmCPackComponent* component) // Licenses if (const char* option = this->GetOption(prefix + "LICENSES")) { this->Licenses.clear(); - cmSystemTools::ExpandListArgument(option, this->Licenses); + cmExpandList(option, this->Licenses); if (this->Licenses.size() % 2 != 0) { cmCPackIFWLogger( WARNING, @@ -281,13 +282,13 @@ int cmCPackIFWPackage::ConfigureFromGroup(cmCPackComponentGroup* group) // User interfaces if (const char* option = this->GetOption(prefix + "USER_INTERFACES")) { this->UserInterfaces.clear(); - cmSystemTools::ExpandListArgument(option, this->UserInterfaces); + cmExpandList(option, this->UserInterfaces); } // Licenses if (const char* option = this->GetOption(prefix + "LICENSES")) { this->Licenses.clear(); - cmSystemTools::ExpandListArgument(option, this->Licenses); + cmExpandList(option, this->Licenses); if (this->Licenses.size() % 2 != 0) { cmCPackIFWLogger( WARNING, @@ -398,18 +399,18 @@ int cmCPackIFWPackage::ConfigureFromPrefix(const std::string& prefix) this->Translations.clear(); } else if (const char* value = this->GetOption(option)) { this->Translations.clear(); - cmSystemTools::ExpandListArgument(value, this->Translations); + cmExpandList(value, this->Translations); } // QtIFW dependencies std::vector<std::string> deps; option = prefix + "DEPENDS"; if (const char* value = this->GetOption(option)) { - cmSystemTools::ExpandListArgument(value, deps); + cmExpandList(value, deps); } option = prefix + "DEPENDENCIES"; if (const char* value = this->GetOption(option)) { - cmSystemTools::ExpandListArgument(value, deps); + cmExpandList(value, deps); } for (std::string const& d : deps) { DependenceStruct dep(d); @@ -430,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; - cmSystemTools::ExpandListArgument(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)) { @@ -488,7 +488,7 @@ int cmCPackIFWPackage::ConfigureFromPrefix(const std::string& prefix) this->Replaces.clear(); } else if (const char* value = this->GetOption(option)) { this->Replaces.clear(); - cmSystemTools::ExpandListArgument(value, this->Replaces); + cmExpandList(value, this->Replaces); } // Requires admin rights diff --git a/Source/CPack/WiX/cmCMakeToWixPath.cxx b/Source/CPack/WiX/cmCMakeToWixPath.cxx index b3889cf..630a8f8 100644 --- a/Source/CPack/WiX/cmCMakeToWixPath.cxx +++ b/Source/CPack/WiX/cmCMakeToWixPath.cxx @@ -2,7 +2,7 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmCMakeToWixPath.h" -#include "cmSystemTools.h" +#include "cmStringAlgorithms.h" #include <string> #include <vector> @@ -29,7 +29,7 @@ std::string CMakeToWixPath(const std::string& cygpath) return cygpath; } - return cmSystemTools::TrimWhitespace(winpath_chars.data()); + return cmTrimWhitespace(winpath_chars.data()); } #else std::string CMakeToWixPath(const std::string& path) diff --git a/Source/CPack/WiX/cmCPackWIXGenerator.cxx b/Source/CPack/WiX/cmCPackWIXGenerator.cxx index 045d93d..b0b2df2 100644 --- a/Source/CPack/WiX/cmCPackWIXGenerator.cxx +++ b/Source/CPack/WiX/cmCPackWIXGenerator.cxx @@ -2,13 +2,16 @@ 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" #include "cmGeneratedFileStream.h" #include "cmInstalledFile.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmUuid.h" +#include "cm_string_view.hxx" #include <algorithm> #include "cmWIXDirectoriesSourceWriter.h" @@ -225,8 +228,7 @@ bool cmCPackWIXGenerator::InitializeWiXConfiguration() const char* patchFilePath = GetOption("CPACK_WIX_PATCH_FILE"); if (patchFilePath) { - std::vector<std::string> patchFilePaths; - cmSystemTools::ExpandListArgument(patchFilePath, patchFilePaths); + std::vector<std::string> patchFilePaths = cmExpandedList(patchFilePath); for (std::string const& p : patchFilePaths) { if (!this->Patch->LoadFragments(p)) { @@ -237,7 +239,7 @@ bool cmCPackWIXGenerator::InitializeWiXConfiguration() // if install folder is supposed to be set absolutely, the default // component guid "*" cannot be used - if (cmSystemTools::IsOn(GetOption("CPACK_WIX_SKIP_PROGRAM_FOLDER"))) { + if (cmIsOn(GetOption("CPACK_WIX_SKIP_PROGRAM_FOLDER"))) { this->ComponentGuidType = cmWIXSourceWriter::CMAKE_GENERATED_GUID; } @@ -300,7 +302,7 @@ void cmCPackWIXGenerator::AppendUserSuppliedExtraSources() if (!cpackWixExtraSources) return; - cmSystemTools::ExpandListArgument(cpackWixExtraSources, this->WixSources); + cmExpandList(cpackWixExtraSources, this->WixSources); } void cmCPackWIXGenerator::AppendUserSuppliedExtraObjects(std::ostream& stream) @@ -309,10 +311,8 @@ void cmCPackWIXGenerator::AppendUserSuppliedExtraObjects(std::ostream& stream) if (!cpackWixExtraObjects) return; - std::vector<std::string> expandedExtraObjects; - - cmSystemTools::ExpandListArgument(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; @@ -582,7 +580,7 @@ bool cmCPackWIXGenerator::CreateWiXSourceFiles() std::string cmCPackWIXGenerator::GetRootFolderId() const { - if (cmSystemTools::IsOn(GetOption("CPACK_WIX_SKIP_PROGRAM_FOLDER"))) { + if (cmIsOn(GetOption("CPACK_WIX_SKIP_PROGRAM_FOLDER"))) { return ""; } @@ -604,7 +602,7 @@ std::string cmCPackWIXGenerator::GetRootFolderId() const bool cmCPackWIXGenerator::GenerateMainSourceFileFromTemplate() { - std::string wixTemplate = FindTemplate("WIX.template.in"); + std::string wixTemplate = FindTemplate("Internal/CPack/WIX.template.in"); if (GetOption("CPACK_WIX_TEMPLATE") != 0) { wixTemplate = GetOption("CPACK_WIX_TEMPLATE"); } @@ -664,8 +662,7 @@ bool cmCPackWIXGenerator::AddComponentsToFeature( std::vector<std::string> cpackPackageExecutablesList; const char* cpackPackageExecutables = GetOption("CPACK_PACKAGE_EXECUTABLES"); if (cpackPackageExecutables) { - cmSystemTools::ExpandListArgument(cpackPackageExecutables, - cpackPackageExecutablesList); + cmExpandList(cpackPackageExecutables, cpackPackageExecutablesList); if (cpackPackageExecutablesList.size() % 2 != 0) { cmCPackLogger( cmCPackLog::LOG_ERROR, @@ -680,8 +677,7 @@ bool cmCPackWIXGenerator::AddComponentsToFeature( const char* cpackPackageDesktopLinks = GetOption("CPACK_CREATE_DESKTOP_LINKS"); if (cpackPackageDesktopLinks) { - cmSystemTools::ExpandListArgument(cpackPackageDesktopLinks, - cpackPackageDesktopLinksList); + cmExpandList(cpackPackageDesktopLinks, cpackPackageDesktopLinksList); } AddDirectoryAndFileDefinitions( @@ -944,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); } } @@ -1090,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) { @@ -1136,8 +1129,7 @@ void cmCPackWIXGenerator::CollectExtensions(std::string const& variableName, if (!variableContent) return; - std::vector<std::string> list; - cmSystemTools::ExpandListArgument(variableContent, list); + std::vector<std::string> list = cmExpandedList(variableContent); extensions.insert(list.begin(), list.end()); } @@ -1148,8 +1140,7 @@ void cmCPackWIXGenerator::AddCustomFlags(std::string const& variableName, if (!variableContent) return; - std::vector<std::string> list; - cmSystemTools::ExpandListArgument(variableContent, list); + std::vector<std::string> list = cmExpandedList(variableContent); for (std::string const& i : list) { stream << " " << QuotePath(i); diff --git a/Source/CPack/WiX/cmWIXAccessControlList.cxx b/Source/CPack/WiX/cmWIXAccessControlList.cxx index 563de02..b5e287d 100644 --- a/Source/CPack/WiX/cmWIXAccessControlList.cxx +++ b/Source/CPack/WiX/cmWIXAccessControlList.cxx @@ -4,6 +4,7 @@ #include "cmCPackGenerator.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" cmWIXAccessControlList::cmWIXAccessControlList( @@ -48,8 +49,7 @@ void cmWIXAccessControlList::CreatePermissionElement(std::string const& entry) user = user_and_domain; } - std::vector<std::string> permissions = - cmSystemTools::tokenize(permission_string, ","); + std::vector<std::string> permissions = cmTokenize(permission_string, ","); this->SourceWriter.BeginElement("Permission"); this->SourceWriter.AddAttribute("User", user); @@ -57,8 +57,7 @@ void cmWIXAccessControlList::CreatePermissionElement(std::string const& entry) this->SourceWriter.AddAttribute("Domain", domain); } for (std::string const& permission : permissions) { - this->EmitBooleanAttribute(entry, - cmSystemTools::TrimWhitespace(permission)); + this->EmitBooleanAttribute(entry, cmTrimWhitespace(permission)); } this->SourceWriter.EndElement("Permission"); } 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 3a476f4..4d5f43f 100644 --- a/Source/CPack/cmCPackBundleGenerator.cxx +++ b/Source/CPack/cmCPackBundleGenerator.cxx @@ -6,6 +6,7 @@ #include <vector> #include "cmCPackLog.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" cmCPackBundleGenerator::cmCPackBundleGenerator() = default; @@ -40,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(); } @@ -89,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; @@ -190,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 = @@ -205,8 +203,7 @@ int cmCPackBundleGenerator::SignBundle(const std::string& src_dir) ? this->GetOption("CPACK_BUNDLE_APPLE_CODESIGN_FILES") : ""; - std::vector<std::string> relFiles; - cmSystemTools::ExpandListArgument(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 cfb5efd..cefbc90 100644 --- a/Source/CPack/cmCPackDebGenerator.cxx +++ b/Source/CPack/cmCPackDebGenerator.cxx @@ -8,6 +8,7 @@ #include "cmCPackLog.h" #include "cmCryptoHash.h" #include "cmGeneratedFileStream.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cm_sys_stat.h" @@ -148,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); } @@ -247,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) || @@ -377,8 +376,7 @@ bool DebGenerator::generateControlTar(std::string const& md5Filename) const // default control_tar.ClearPermissions(); - std::vector<std::string> controlExtraList; - cmSystemTools::ExpandListArgument(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; @@ -439,7 +437,7 @@ cmCPackDebGenerator::~cmCPackDebGenerator() = default; int cmCPackDebGenerator::InitializeInternal() { this->SetOptionIfNotSet("CPACK_PACKAGING_INSTALL_PREFIX", "/usr"); - if (cmSystemTools::IsOff(this->GetOption("CPACK_SET_DESTDIR"))) { + if (cmIsOff(this->GetOption("CPACK_SET_DESTDIR"))) { this->SetOption("CPACK_SET_DESTDIR", "I_ON"); } return this->Superclass::InitializeInternal(); @@ -468,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")) { @@ -499,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")) { @@ -523,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)); } @@ -613,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()); } @@ -643,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 7a3742b..ca06b81 100644 --- a/Source/CPack/cmCPackDragNDropGenerator.cxx +++ b/Source/CPack/cmCPackDragNDropGenerator.cxx @@ -6,6 +6,7 @@ #include "cmCPackLog.h" #include "cmDuration.h" #include "cmGeneratedFileStream.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmsys/FStream.hxx" @@ -127,9 +128,8 @@ int cmCPackDragNDropGenerator::InitializeInternal() return 0; } - std::vector<std::string> languages; - cmSystemTools::ExpandListArgument( - 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,12 +520,12 @@ 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) { - cmSystemTools::ExpandListArgument(cpack_dmg_languages, languages); + cmExpandList(cpack_dmg_languages, languages); } cmGeneratedFileStream ofs(sla_r); @@ -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/cmCPackExternalGenerator.cxx b/Source/CPack/cmCPackExternalGenerator.cxx index 9dc9853..5dc6ace 100644 --- a/Source/CPack/cmCPackExternalGenerator.cxx +++ b/Source/CPack/cmCPackExternalGenerator.cxx @@ -2,10 +2,10 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmCPackExternalGenerator.h" -#include "cmAlgorithms.h" #include "cmCPackComponentGroup.h" #include "cmCPackLog.h" #include "cmMakefile.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cm_jsoncpp_value.h" @@ -17,6 +17,8 @@ #include <utility> #include <vector> +#include "cm_memory.hxx" + int cmCPackExternalGenerator::InitializeInternal() { this->SetOption("CPACK_EXTERNAL_KNOWN_VERSIONS", "1.0"); @@ -148,8 +150,7 @@ int cmCPackExternalGenerator::InstallCMakeProject( bool cmCPackExternalGenerator::StagingEnabled() const { - return !cmSystemTools::IsOff( - this->GetOption("CPACK_EXTERNAL_ENABLE_STAGING")); + return !cmIsOff(this->GetOption("CPACK_EXTERNAL_ENABLE_STAGING")); } cmCPackExternalGenerator::cmCPackExternalVersionGenerator:: @@ -207,8 +208,7 @@ int cmCPackExternalGenerator::cmCPackExternalVersionGenerator::WriteToJSON( if (defaultDirectoryPermissions && *defaultDirectoryPermissions) { root["defaultDirectoryPermissions"] = defaultDirectoryPermissions; } - if (cmSystemTools::IsInternallyOn( - this->Parent->GetOption("CPACK_SET_DESTDIR"))) { + if (cmIsInternallyOn(this->Parent->GetOption("CPACK_SET_DESTDIR"))) { root["setDestdir"] = true; root["packagingInstallPrefix"] = this->Parent->GetOption("CPACK_PACKAGING_INSTALL_PREFIX"); @@ -216,8 +216,7 @@ int cmCPackExternalGenerator::cmCPackExternalVersionGenerator::WriteToJSON( root["setDestdir"] = false; } - root["stripFiles"] = - !cmSystemTools::IsOff(this->Parent->GetOption("CPACK_STRIP_FILES")); + root["stripFiles"] = !cmIsOff(this->Parent->GetOption("CPACK_STRIP_FILES")); root["warnOnAbsoluteInstallDestination"] = this->Parent->IsOn("CPACK_WARN_ON_ABSOLUTE_INSTALL_DESTINATION"); root["errorOnAbsoluteInstallDestination"] = diff --git a/Source/CPack/cmCPackFreeBSDGenerator.cxx b/Source/CPack/cmCPackFreeBSDGenerator.cxx index 9fdafa4..a35977c 100644 --- a/Source/CPack/cmCPackFreeBSDGenerator.cxx +++ b/Source/CPack/cmCPackFreeBSDGenerator.cxx @@ -6,6 +6,7 @@ #include "cmCPackArchiveGenerator.h" #include "cmCPackLog.h" #include "cmGeneratedFileStream.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" // Needed for ::open() and ::stat() @@ -227,9 +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; - cmSystemTools::ExpandListArgument( - 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,14 +238,12 @@ void cmCPackFreeBSDGenerator::write_manifest_fields( } manifest << ManifestKeyValue("licenselogic", licenselogic); manifest << (ManifestKeyListValue("licenses") << licenses); - std::vector<std::string> categories; - cmSystemTools::ExpandListArgument( - 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; - cmSystemTools::ExpandListArgument(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 7e07ff4..288d5d8 100644 --- a/Source/CPack/cmCPackGenerator.cxx +++ b/Source/CPack/cmCPackGenerator.cxx @@ -7,7 +7,7 @@ #include "cmsys/RegularExpression.hxx" #include <algorithm> #include <cstring> -#include <memory> // IWYU pragma: keep +#include <memory> #include <utility> #include "cmCPackComponentGroup.h" @@ -21,6 +21,7 @@ #include "cmMakefile.h" #include "cmState.h" #include "cmStateSnapshot.h" +#include "cmStringAlgorithms.h" #include "cmVersion.h" #include "cmWorkingDirectory.h" #include "cmXMLSafe.h" @@ -72,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; @@ -179,8 +180,8 @@ int cmCPackGenerator::InstallProject() std::string bareTempInstallDirectory = this->GetOption("CPACK_TEMPORARY_INSTALL_DIRECTORY"); std::string tempInstallDirectoryStr = bareTempInstallDirectory; - bool setDestDir = cmSystemTools::IsOn(this->GetOption("CPACK_SET_DESTDIR")) | - cmSystemTools::IsInternallyOn(this->GetOption("CPACK_SET_DESTDIR")); + bool setDestDir = cmIsOn(this->GetOption("CPACK_SET_DESTDIR")) | + cmIsInternallyOn(this->GetOption("CPACK_SET_DESTDIR")); if (!setDestDir) { tempInstallDirectoryStr += this->GetPackagingInstallPrefix(); } @@ -196,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 @@ -210,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; - cmSystemTools::ExpandListArgument(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, @@ -235,7 +235,7 @@ int cmCPackGenerator::InstallProject() return 0; } - // If the CPackConfig file sets CPACK_INSTALL_SCRIPT then run them + // If the CPackConfig file sets CPACK_INSTALL_SCRIPT(S) then run them // as listed if (!this->InstallProjectViaInstallScript(setDestDir, tempInstallDirectory)) { @@ -270,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; - cmSystemTools::ExpandListArgument(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; @@ -283,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 @@ -310,9 +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; - cmSystemTools::ExpandListArgument(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,9 +321,8 @@ int cmCPackGenerator::InstallProjectViaInstalledDirectories( const char* installDirectories = this->GetOption("CPACK_INSTALLED_DIRECTORIES"); if (installDirectories && *installDirectories) { - std::vector<std::string> installDirectoriesVector; - cmSystemTools::ExpandListArgument(installDirectories, - installDirectoriesVector); + std::vector<std::string> installDirectoriesVector = + cmExpandedList(installDirectories); if (installDirectoriesVector.size() % 2 != 0) { cmCPackLogger( cmCPackLog::LOG_ERROR, @@ -344,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(); @@ -373,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); @@ -399,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); @@ -448,12 +444,23 @@ int cmCPackGenerator::InstallProjectViaInstalledDirectories( int cmCPackGenerator::InstallProjectViaInstallScript( bool setDestDir, const std::string& tempInstallDirectory) { - const char* cmakeScripts = this->GetOption("CPACK_INSTALL_SCRIPT"); + const char* cmakeScripts = this->GetOption("CPACK_INSTALL_SCRIPTS"); + { + const char* const cmakeScript = this->GetOption("CPACK_INSTALL_SCRIPT"); + if (cmakeScript && cmakeScripts) { + cmCPackLogger( + cmCPackLog::LOG_WARNING, + "Both CPACK_INSTALL_SCRIPTS and CPACK_INSTALL_SCRIPT are set, " + "the latter will be ignored." + << std::endl); + } else if (cmakeScript && !cmakeScripts) { + cmakeScripts = cmakeScript; + } + } if (cmakeScripts && *cmakeScripts) { cmCPackLogger(cmCPackLog::LOG_OUTPUT, "- Install scripts: " << cmakeScripts << std::endl); - std::vector<std::string> cmakeScriptsVector; - cmSystemTools::ExpandListArgument(cmakeScripts, cmakeScriptsVector); + std::vector<std::string> cmakeScriptsVector = cmExpandedList(cmakeScripts); for (std::string const& installScript : cmakeScriptsVector) { cmCPackLogger(cmCPackLog::LOG_OUTPUT, @@ -517,8 +524,8 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects( << std::endl); return 0; } - std::vector<std::string> cmakeProjectsVector; - cmSystemTools::ExpandListArgument(cmakeProjects, cmakeProjectsVector); + std::vector<std::string> cmakeProjectsVector = + cmExpandedList(cmakeProjects); std::vector<std::string>::iterator it; for (it = cmakeProjectsVector.begin(); it != cmakeProjectsVector.end(); ++it) { @@ -562,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; - cmSystemTools::ExpandListArgument(installTypes, installTypesVector); + std::vector<std::string> installTypesVector = + cmExpandedList(installTypes); for (std::string const& installType : installTypesVector) { project.InstallationTypes.push_back( this->GetInstallationType(project.ProjectName, installType)); @@ -575,7 +582,7 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects( "CPACK_COMPONENTS_" + cmSystemTools::UpperCase(project.Component); const char* components = this->GetOption(componentsVar); if (components && *components) { - cmSystemTools::ExpandListArgument(components, componentsVector); + cmExpandList(components, componentsVector); for (std::string const& comp : componentsVector) { project.Components.push_back( this->GetComponent(project.ProjectName, comp)); @@ -651,8 +658,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 @@ -739,7 +746,7 @@ int cmCPackGenerator::InstallCMakeProject( // CPACK_PACKAGING_INSTALL_PREFIX // I know this is tricky and awkward but it's the price for // CPACK_SET_DESTDIR backward compatibility. - if (cmSystemTools::IsInternallyOn(this->GetOption("CPACK_SET_DESTDIR"))) { + if (cmIsInternallyOn(this->GetOption("CPACK_SET_DESTDIR"))) { this->SetOption("CPACK_INSTALL_PREFIX", this->GetOption("CPACK_PACKAGING_INSTALL_PREFIX")); } @@ -747,7 +754,7 @@ int cmCPackGenerator::InstallCMakeProject( if (this->GetOption("CPACK_INSTALL_PREFIX")) { dir += this->GetOption("CPACK_INSTALL_PREFIX"); } - mf.AddDefinition("CMAKE_INSTALL_PREFIX", dir.c_str()); + mf.AddDefinition("CMAKE_INSTALL_PREFIX", dir); cmCPackLogger( cmCPackLog::LOG_DEBUG, @@ -760,7 +767,7 @@ int cmCPackGenerator::InstallCMakeProject( // Make sure that DESTDIR + CPACK_INSTALL_PREFIX directory // exists: // - if (cmSystemTools::StringStartsWith(dir.c_str(), "/")) { + if (cmHasLiteralPrefix(dir, "/")) { dir = tempInstallDirectory + dir; } else { dir = tempInstallDirectory + "/" + dir; @@ -787,7 +794,7 @@ int cmCPackGenerator::InstallCMakeProject( return 0; } } else { - mf.AddDefinition("CMAKE_INSTALL_PREFIX", tempInstallDirectory.c_str()); + mf.AddDefinition("CMAKE_INSTALL_PREFIX", tempInstallDirectory); if (!cmsys::SystemTools::MakeDirectory(tempInstallDirectory, default_dir_mode)) { @@ -806,16 +813,16 @@ int cmCPackGenerator::InstallCMakeProject( } if (!buildConfig.empty()) { - mf.AddDefinition("BUILD_TYPE", buildConfig.c_str()); + mf.AddDefinition("BUILD_TYPE", buildConfig); } std::string installComponentLowerCase = cmSystemTools::LowerCase(component); if (installComponentLowerCase != "all") { - mf.AddDefinition("CMAKE_INSTALL_COMPONENT", component.c_str()); + mf.AddDefinition("CMAKE_INSTALL_COMPONENT", component); } // strip on TRUE, ON, 1, one or several file names, but not on // FALSE, OFF, 0 and an empty string - if (!cmSystemTools::IsOff(this->GetOption("CPACK_STRIP_FILES"))) { + if (!cmIsOff(this->GetOption("CPACK_STRIP_FILES"))) { mf.AddDefinition("CMAKE_INSTALL_DO_STRIP", "1"); } // Remember the list of files before installation @@ -851,9 +858,8 @@ int cmCPackGenerator::InstallCMakeProject( // forward definition of CMAKE_ABSOLUTE_DESTINATION_FILES // to CPack (may be used by generators like CPack RPM or DEB) // in order to transparently handle ABSOLUTE PATH - if (mf.GetDefinition("CMAKE_ABSOLUTE_DESTINATION_FILES")) { - mf.AddDefinition("CPACK_ABSOLUTE_DESTINATION_FILES", - mf.GetDefinition("CMAKE_ABSOLUTE_DESTINATION_FILES")); + if (const char* def = mf.GetDefinition("CMAKE_ABSOLUTE_DESTINATION_FILES")) { + mf.AddDefinition("CPACK_ABSOLUTE_DESTINATION_FILES", def); } // Now rebuild the list of files after installation @@ -901,10 +907,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 { @@ -967,8 +971,7 @@ int cmCPackGenerator::DoPackage() return 0; } - if (cmSystemTools::IsOn( - this->GetOption("CPACK_REMOVE_TOPLEVEL_DIRECTORY"))) { + if (cmIsOn(this->GetOption("CPACK_REMOVE_TOPLEVEL_DIRECTORY"))) { const char* toplevelDirectory = this->GetOption("CPACK_TOPLEVEL_DIRECTORY"); if (cmSystemTools::FileExists(toplevelDirectory)) { @@ -997,8 +1000,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); @@ -1018,8 +1020,7 @@ int cmCPackGenerator::DoPackage() "Remove old package file" << std::endl); cmSystemTools::RemoveFile(tempPackageFileName); } - if (cmSystemTools::IsOn( - this->GetOption("CPACK_INCLUDE_TOPLEVEL_DIRECTORY"))) { + if (cmIsOn(this->GetOption("CPACK_INCLUDE_TOPLEVEL_DIRECTORY"))) { tempDirectory = this->GetOption("CPACK_TOPLEVEL_DIRECTORY"); } @@ -1143,14 +1144,14 @@ bool cmCPackGenerator::IsSet(const std::string& name) const bool cmCPackGenerator::IsOn(const std::string& name) const { - return cmSystemTools::IsOn(GetOption(name)); + return cmIsOn(GetOption(name)); } bool cmCPackGenerator::IsSetToOff(const std::string& op) const { const char* ret = this->MakefileMap->GetDefinition(op); if (ret && *ret) { - return cmSystemTools::IsOff(ret); + return cmIsOff(ret); } return false; } @@ -1195,8 +1196,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"; } @@ -1464,7 +1464,7 @@ cmCPackComponent* cmCPackGenerator::GetComponent( component->IsRequired = this->IsOn(macroPrefix + "_REQUIRED"); component->IsDisabledByDefault = this->IsOn(macroPrefix + "_DISABLED"); component->IsDownloaded = this->IsOn(macroPrefix + "_DOWNLOADED") || - cmSystemTools::IsOn(this->GetOption("CPACK_DOWNLOAD_ALL")); + cmIsOn(this->GetOption("CPACK_DOWNLOAD_ALL")); const char* archiveFile = this->GetOption(macroPrefix + "_ARCHIVE_FILE"); if (archiveFile && *archiveFile) { @@ -1492,8 +1492,8 @@ cmCPackComponent* cmCPackGenerator::GetComponent( // Determine the installation types. const char* installTypes = this->GetOption(macroPrefix + "_INSTALL_TYPES"); if (installTypes && *installTypes) { - std::vector<std::string> installTypesVector; - cmSystemTools::ExpandListArgument(installTypes, installTypesVector); + std::vector<std::string> installTypesVector = + cmExpandedList(installTypes); for (std::string const& installType : installTypesVector) { component->InstallationTypes.push_back( this->GetInstallationType(projectName, installType)); @@ -1503,8 +1503,7 @@ cmCPackComponent* cmCPackGenerator::GetComponent( // Determine the component dependencies. const char* depends = this->GetOption(macroPrefix + "_DEPENDS"); if (depends && *depends) { - std::vector<std::string> dependsVector; - cmSystemTools::ExpandListArgument(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 e2020c5..8098edf 100644 --- a/Source/CPack/cmCPackNSISGenerator.cxx +++ b/Source/CPack/cmCPackNSISGenerator.cxx @@ -2,11 +2,13 @@ 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" #include "cmDuration.h" #include "cmGeneratedFileStream.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmsys/Directory.hxx" @@ -36,7 +38,8 @@ int cmCPackNSISGenerator::PackageFiles() { // TODO: Fix nsis to force out file name - std::string nsisInFileName = this->FindTemplate("NSIS.template.in"); + std::string nsisInFileName = + this->FindTemplate("Internal/CPack/NSIS.template.in"); if (nsisInFileName.empty()) { cmCPackLogger(cmCPackLog::LOG_ERROR, "CPack error: Could not find NSIS installer template file." @@ -44,7 +47,7 @@ int cmCPackNSISGenerator::PackageFiles() return false; } std::string nsisInInstallOptions = - this->FindTemplate("NSIS.InstallOptions.ini.in"); + this->FindTemplate("Internal/CPack/NSIS.InstallOptions.ini.in"); if (nsisInInstallOptions.empty()) { cmCPackLogger(cmCPackLog::LOG_ERROR, "CPack error: Could not find NSIS installer options file." @@ -53,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; @@ -139,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()); } @@ -273,7 +270,7 @@ int cmCPackNSISGenerator::PackageFiles() if (anyDownloadedComponents) { defines += "!define CPACK_USES_DOWNLOAD\n"; - if (cmSystemTools::IsOn(this->GetOption("CPACK_ADD_REMOVE"))) { + if (cmIsOn(this->GetOption("CPACK_ADD_REMOVE"))) { defines += "!define CPACK_NSIS_ADD_REMOVE\n"; } } @@ -294,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; @@ -320,8 +317,7 @@ int cmCPackNSISGenerator::PackageFiles() int cmCPackNSISGenerator::InitializeInternal() { - if (cmSystemTools::IsOn( - this->GetOption("CPACK_INCLUDE_TOPLEVEL_DIRECTORY"))) { + if (cmIsOn(this->GetOption("CPACK_INCLUDE_TOPLEVEL_DIRECTORY"))) { cmCPackLogger( cmCPackLog::LOG_WARNING, "NSIS Generator cannot work with CPACK_INCLUDE_TOPLEVEL_DIRECTORY set. " @@ -413,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 @@ -458,8 +453,7 @@ int cmCPackNSISGenerator::InitializeInternal() "CPACK_CREATE_DESKTOP_LINKS: " << cpackPackageDeskTopLinks << std::endl); - cmSystemTools::ExpandListArgument(cpackPackageDeskTopLinks, - cpackPackageDesktopLinksVector); + cmExpandList(cpackPackageDeskTopLinks, cpackPackageDesktopLinksVector); for (std::string const& cpdl : cpackPackageDesktopLinksVector) { cmCPackLogger(cmCPackLog::LOG_DEBUG, "CPACK_CREATE_DESKTOP_LINKS: " << cpdl << std::endl); @@ -477,9 +471,8 @@ int cmCPackNSISGenerator::InitializeInternal() cmCPackLogger(cmCPackLog::LOG_DEBUG, "The cpackPackageExecutables: " << cpackPackageExecutables << "." << std::endl); - std::vector<std::string> cpackPackageExecutablesVector; - cmSystemTools::ExpandListArgument(cpackPackageExecutables, - cpackPackageExecutablesVector); + std::vector<std::string> cpackPackageExecutablesVector = + cmExpandedList(cpackPackageExecutables); if (cpackPackageExecutablesVector.size() % 2 != 0) { cmCPackLogger( cmCPackLog::LOG_ERROR, @@ -501,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 << "\\" @@ -534,8 +524,8 @@ void cmCPackNSISGenerator::CreateMenuLinks(std::ostream& str, } cmCPackLogger(cmCPackLog::LOG_DEBUG, "The cpackMenuLinks: " << cpackMenuLinks << "." << std::endl); - std::vector<std::string> cpackMenuLinksVector; - cmSystemTools::ExpandListArgument(cpackMenuLinks, cpackMenuLinksVector); + std::vector<std::string> cpackMenuLinksVector = + cmExpandedList(cpackMenuLinks); if (cpackMenuLinksVector.size() % 2 != 0) { cmCPackLogger( cmCPackLog::LOG_ERROR, @@ -576,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 @@ -659,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"; @@ -674,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)) { @@ -712,17 +701,14 @@ 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"; - bool needQuotesInFile = - cmSystemTools::IsOn(this->GetOption("CPACK_ZIP_NEED_QUOTES")); + 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 cmGeneratedFileStream out(zipListFileName); @@ -751,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/cmCPackNuGetGenerator.cxx b/Source/CPack/cmCPackNuGetGenerator.cxx index 76f0699..19a3a0a 100644 --- a/Source/CPack/cmCPackNuGetGenerator.cxx +++ b/Source/CPack/cmCPackNuGetGenerator.cxx @@ -2,9 +2,9 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmCPackNuGetGenerator.h" -#include "cmAlgorithms.h" #include "cmCPackComponentGroup.h" #include "cmCPackLog.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include <algorithm> diff --git a/Source/CPack/cmCPackOSXX11Generator.cxx b/Source/CPack/cmCPackOSXX11Generator.cxx index 90e0afe..992299a 100644 --- a/Source/CPack/cmCPackOSXX11Generator.cxx +++ b/Source/CPack/cmCPackOSXX11Generator.cxx @@ -8,6 +8,7 @@ #include "cmCPackLog.h" #include "cmDuration.h" #include "cmGeneratedFileStream.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cm_sys_stat.h" @@ -28,9 +29,8 @@ int cmCPackOSXX11Generator::PackageFiles() << "." << std::endl); std::ostringstream str; std::ostringstream deleteStr; - std::vector<std::string> cpackPackageExecutablesVector; - cmSystemTools::ExpandListArgument(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 = "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 8c22c65..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"; @@ -48,7 +49,7 @@ std::string cmCPackPKGGenerator::GetPackageName( void cmCPackPKGGenerator::WriteDistributionFile(const char* metapackageFile) { std::string distributionTemplate = - this->FindTemplate("CPack.distribution.dist.in"); + this->FindTemplate("Internal/CPack/CPack.distribution.dist.in"); if (distributionTemplate.empty()) { cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot find input file: " << distributionTemplate @@ -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 = "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 33ab62b..0f621cc 100644 --- a/Source/CPack/cmCPackRPMGenerator.cxx +++ b/Source/CPack/cmCPackRPMGenerator.cxx @@ -12,6 +12,7 @@ #include "cmCPackComponentGroup.h" #include "cmCPackGenerator.h" #include "cmCPackLog.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" cmCPackRPMGenerator::cmCPackRPMGenerator() = default; @@ -21,7 +22,7 @@ cmCPackRPMGenerator::~cmCPackRPMGenerator() = default; int cmCPackRPMGenerator::InitializeInternal() { this->SetOptionIfNotSet("CPACK_PACKAGING_INSTALL_PREFIX", "/usr"); - if (cmSystemTools::IsOff(this->GetOption("CPACK_SET_DESTDIR"))) { + if (cmIsOff(this->GetOption("CPACK_SET_DESTDIR"))) { this->SetOption("CPACK_SET_DESTDIR", "I_ON"); } /* Replace space in CPACK_PACKAGE_NAME in order to avoid @@ -81,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")) { @@ -375,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/cmCPackSTGZGenerator.cxx b/Source/CPack/cmCPackSTGZGenerator.cxx index aba15d2..4666dc2 100644 --- a/Source/CPack/cmCPackSTGZGenerator.cxx +++ b/Source/CPack/cmCPackSTGZGenerator.cxx @@ -21,7 +21,8 @@ int cmCPackSTGZGenerator::InitializeInternal() { this->SetOptionIfNotSet("CPACK_INCLUDE_TOPLEVEL_DIRECTORY", "0"); - std::string inFile = this->FindTemplate("CPack.STGZ_Header.sh.in"); + std::string inFile = + this->FindTemplate("Internal/CPack/CPack.STGZ_Header.sh.in"); if (inFile.empty()) { cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot find template file: " << inFile << std::endl); diff --git a/Source/CPack/cpack.cxx b/Source/CPack/cpack.cxx index 58b9e70..69dac88 100644 --- a/Source/CPack/cpack.cxx +++ b/Source/CPack/cpack.cxx @@ -1,21 +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 <memory> // IWYU pragma: keep -#include <sstream> -#include <stddef.h> -#include <string> -#include <utility> -#include <vector> - -#if defined(_WIN32) && defined(CMAKE_BUILD_WITH_CMAKE) -# include "cmsys/ConsoleBuf.hxx" -#endif - #include "cmCPackGenerator.h" #include "cmCPackGeneratorFactory.h" #include "cmCPackLog.h" @@ -26,22 +11,39 @@ #include "cmMakefile.h" #include "cmState.h" #include "cmStateSnapshot.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmake.h" -static const char* cmDocumentationName[][2] = { +#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." }, { nullptr, nullptr } }; -static const char* cmDocumentationUsage[][2] = { +const char* cmDocumentationUsage[][2] = { // clang-format off { nullptr, " cpack [options]" }, { nullptr, nullptr } // clang-format on }; -static const char* cmDocumentationOptions[][2] = { +const char* cmDocumentationOptions[][2] = { { "-G <generators>", "Override/define CPACK_GENERATOR" }, { "-C <Configuration>", "Specify the project configuration" }, { "-D <var>=<value>", "Set a CPack variable." }, @@ -90,16 +92,17 @@ int cpackDefinitionArgument(const char* argument, const char* cValue, return 1; } -static void cpackProgressCallback(const std::string& message, float /*unused*/) +void cpackProgressCallback(const std::string& message, float /*unused*/) { std::cout << "-- " << message << std::endl; } +} // namespace // this is CPack. int main(int argc, char const* const* argv) { cmSystemTools::EnsureStdPipes(); -#if defined(_WIN32) && defined(CMAKE_BUILD_WITH_CMAKE) +#if defined(_WIN32) && !defined(CMAKE_BOOTSTRAP) // Replace streambuf so we can output Unicode to console cmsys::ConsoleBuf::Manager consoleOut(std::cout); consoleOut.SetUTF8Pipes(); @@ -227,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; } @@ -269,7 +272,7 @@ int main(int argc, char const* const* argv) } if (!cpackBuildConfig.empty()) { - globalMF.AddDefinition("CPACK_BUILD_CONFIG", cpackBuildConfig.c_str()); + globalMF.AddDefinition("CPACK_BUILD_CONFIG", cpackBuildConfig); } if (cmSystemTools::FileExists(cpackConfigFile)) { @@ -291,24 +294,21 @@ int main(int argc, char const* const* argv) } if (!generator.empty()) { - globalMF.AddDefinition("CPACK_GENERATOR", generator.c_str()); + globalMF.AddDefinition("CPACK_GENERATOR", generator); } if (!cpackProjectName.empty()) { - globalMF.AddDefinition("CPACK_PACKAGE_NAME", cpackProjectName.c_str()); + globalMF.AddDefinition("CPACK_PACKAGE_NAME", cpackProjectName); } if (!cpackProjectVersion.empty()) { - globalMF.AddDefinition("CPACK_PACKAGE_VERSION", - cpackProjectVersion.c_str()); + globalMF.AddDefinition("CPACK_PACKAGE_VERSION", cpackProjectVersion); } if (!cpackProjectVendor.empty()) { - globalMF.AddDefinition("CPACK_PACKAGE_VENDOR", - cpackProjectVendor.c_str()); + globalMF.AddDefinition("CPACK_PACKAGE_VENDOR", cpackProjectVendor); } // if this is not empty it has been set on the command line // go for it. Command line override values set in config file. if (!cpackProjectDirectory.empty()) { - globalMF.AddDefinition("CPACK_PACKAGE_DIRECTORY", - cpackProjectDirectory.c_str()); + globalMF.AddDefinition("CPACK_PACKAGE_DIRECTORY", cpackProjectDirectory); } // The value has not been set on the command line else { @@ -317,11 +317,11 @@ int main(int argc, char const* const* argv) // use default value iff no value has been provided by the config file if (!globalMF.IsSet("CPACK_PACKAGE_DIRECTORY")) { globalMF.AddDefinition("CPACK_PACKAGE_DIRECTORY", - cpackProjectDirectory.c_str()); + cpackProjectDirectory); } } for (auto const& cd : definitions.Map) { - globalMF.AddDefinition(cd.first, cd.second.c_str()); + globalMF.AddDefinition(cd.first, cd.second); } const char* cpackModulesPath = globalMF.GetDefinition("CPACK_MODULE_PATH"); @@ -333,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; - cmSystemTools::ExpandListArgument(genList, generatorsVector); + std::vector<std::string> generatorsVector = cmExpandedList(genList); for (std::string const& gen : generatorsVector) { cmMakefile::ScopePushPop raii(&globalMF); cmMakefile* mf = &globalMF; @@ -425,7 +424,7 @@ int main(int argc, char const* const* argv) std::ostringstream ostr; ostr << projVersionMajor << "." << projVersionMinor << "." << projVersionPatch; - mf->AddDefinition("CPACK_PACKAGE_VERSION", ostr.str().c_str()); + mf->AddDefinition("CPACK_PACKAGE_VERSION", ostr.str()); } int res = cpackGenerator->DoPackage(); diff --git a/Source/CTest/cmCTestBuildAndTestHandler.cxx b/Source/CTest/cmCTestBuildAndTestHandler.cxx index 9ad9669..e7fb4c7 100644 --- a/Source/CTest/cmCTestBuildAndTestHandler.cxx +++ b/Source/CTest/cmCTestBuildAndTestHandler.cxx @@ -7,6 +7,7 @@ #include "cmGlobalGenerator.h" #include "cmMakefile.h" #include "cmState.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmWorkingDirectory.h" #include "cmake.h" @@ -76,6 +77,11 @@ int cmCTestBuildAndTestHandler::RunCMake(std::string* outstring, if (config) { args.push_back("-DCMAKE_BUILD_TYPE:STRING=" + std::string(config)); } + if (!this->BuildMakeProgram.empty() && + (this->BuildGenerator.find("Make") != std::string::npos || + this->BuildGenerator.find("Ninja") != std::string::npos)) { + args.push_back("-DCMAKE_MAKE_PROGRAM:FILEPATH=" + this->BuildMakeProgram); + } for (std::string const& opt : this->BuildOptions) { args.push_back(opt); @@ -284,9 +290,8 @@ int cmCTestBuildAndTestHandler::RunCMakeAndTest(std::string* outstring) std::vector<std::string> extraPaths; // if this->ExecutableDirectory is set try that as well if (!this->ExecutableDirectory.empty()) { - std::string tempPath = this->ExecutableDirectory; - tempPath += "/"; - tempPath += this->TestCommand; + std::string tempPath = + cmStrCat(this->ExecutableDirectory, '/', this->TestCommand); extraPaths.push_back(tempPath); } std::vector<std::string> failed; diff --git a/Source/CTest/cmCTestBuildCommand.cxx b/Source/CTest/cmCTestBuildCommand.cxx index 2eacaf1..cb22fa6 100644 --- a/Source/CTest/cmCTestBuildCommand.cxx +++ b/Source/CTest/cmCTestBuildCommand.cxx @@ -7,6 +7,7 @@ #include "cmGlobalGenerator.h" #include "cmMakefile.h" #include "cmMessageType.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmake.h" @@ -90,9 +91,8 @@ cmCTestGenericHandler* cmCTestBuildCommand::InitializeHandler() this->Makefile->GetCMakeInstance()->CreateGlobalGenerator( cmakeGeneratorName); if (!this->GlobalGenerator) { - std::string e = "could not create generator named \""; - e += cmakeGeneratorName; - e += "\""; + std::string e = cmStrCat("could not create generator named \"", + cmakeGeneratorName, '"'); this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e); cmSystemTools::SetFatalErrorOccured(); return nullptr; @@ -154,17 +154,15 @@ bool cmCTestBuildCommand::InitialPass(std::vector<std::string> const& args, { bool ret = cmCTestHandlerCommand::InitialPass(args, status); if (this->Values[ctb_NUMBER_ERRORS] && *this->Values[ctb_NUMBER_ERRORS]) { - std::ostringstream str; - str << this->Handler->GetTotalErrors(); - this->Makefile->AddDefinition(this->Values[ctb_NUMBER_ERRORS], - str.str().c_str()); + this->Makefile->AddDefinition( + this->Values[ctb_NUMBER_ERRORS], + std::to_string(this->Handler->GetTotalErrors())); } if (this->Values[ctb_NUMBER_WARNINGS] && *this->Values[ctb_NUMBER_WARNINGS]) { - std::ostringstream str; - str << this->Handler->GetTotalWarnings(); - this->Makefile->AddDefinition(this->Values[ctb_NUMBER_WARNINGS], - str.str().c_str()); + this->Makefile->AddDefinition( + this->Values[ctb_NUMBER_WARNINGS], + std::to_string(this->Handler->GetTotalWarnings())); } return ret; } diff --git a/Source/CTest/cmCTestBuildCommand.h b/Source/CTest/cmCTestBuildCommand.h index 77b0549..a62c301 100644 --- a/Source/CTest/cmCTestBuildCommand.h +++ b/Source/CTest/cmCTestBuildCommand.h @@ -6,13 +6,16 @@ #include "cmConfigure.h" // IWYU pragma: keep #include "cmCTestHandlerCommand.h" +#include "cmCommand.h" #include <string> +#include <utility> #include <vector> +#include "cm_memory.hxx" + class cmCTestBuildHandler; class cmCTestGenericHandler; -class cmCommand; class cmExecutionStatus; class cmGlobalGenerator; @@ -30,12 +33,12 @@ public: /** * This is a virtual constructor for the command. */ - cmCommand* Clone() override + std::unique_ptr<cmCommand> Clone() override { - cmCTestBuildCommand* ni = new cmCTestBuildCommand; + auto ni = cm::make_unique<cmCTestBuildCommand>(); ni->CTest = this->CTest; ni->CTestScriptHandler = this->CTestScriptHandler; - return ni; + return std::unique_ptr<cmCommand>(std::move(ni)); } /** diff --git a/Source/CTest/cmCTestBuildHandler.cxx b/Source/CTest/cmCTestBuildHandler.cxx index c8e4fa1..147286e 100644 --- a/Source/CTest/cmCTestBuildHandler.cxx +++ b/Source/CTest/cmCTestBuildHandler.cxx @@ -9,6 +9,8 @@ #include "cmGeneratedFileStream.h" #include "cmMakefile.h" #include "cmProcessOutput.h" +#include "cmStringAlgorithms.h" +#include "cmStringReplaceHelper.h" #include "cmSystemTools.h" #include "cmXMLWriter.h" @@ -246,13 +248,11 @@ void cmCTestBuildHandler::PopulateCustomVectors(cmMakefile* mf) // Record the user-specified custom warning rules. if (const char* customWarningMatchers = mf->GetDefinition("CTEST_CUSTOM_WARNING_MATCH")) { - cmSystemTools::ExpandListArgument(customWarningMatchers, - this->ReallyCustomWarningMatches); + cmExpandList(customWarningMatchers, this->ReallyCustomWarningMatches); } if (const char* customWarningExceptions = mf->GetDefinition("CTEST_CUSTOM_WARNING_EXCEPTION")) { - cmSystemTools::ExpandListArgument(customWarningExceptions, - this->ReallyCustomWarningExceptions); + cmExpandList(customWarningExceptions, this->ReallyCustomWarningExceptions); } } @@ -327,7 +327,7 @@ int cmCTestBuildHandler::ProcessHandler() std::string const& useLaunchers = this->CTest->GetCTestConfiguration("UseLaunchers"); - this->UseCTestLaunch = cmSystemTools::IsOn(useLaunchers); + this->UseCTestLaunch = cmIsOn(useLaunchers); // Create a last build log cmGeneratedFileStream ofs; @@ -384,11 +384,8 @@ int cmCTestBuildHandler::ProcessHandler() if (this->CTest->GetCTestConfiguration("SourceDirectory").size() > 20) { std::string srcdir = this->CTest->GetCTestConfiguration("SourceDirectory") + "/"; - std::string srcdirrep; for (cc = srcdir.size() - 2; cc > 0; cc--) { if (srcdir[cc] == '/') { - srcdirrep = srcdir.substr(cc); - srcdirrep = "/..." + srcdirrep; srcdir = srcdir.substr(0, cc + 1); break; } @@ -398,11 +395,8 @@ int cmCTestBuildHandler::ProcessHandler() if (this->CTest->GetCTestConfiguration("BuildDirectory").size() > 20) { std::string bindir = this->CTest->GetCTestConfiguration("BuildDirectory") + "/"; - std::string bindirrep; for (cc = bindir.size() - 2; cc > 0; cc--) { if (bindir[cc] == '/') { - bindirrep = bindir.substr(cc); - bindirrep = "/..." + bindirrep; bindir = bindir.substr(0, cc + 1); break; } @@ -415,6 +409,9 @@ int cmCTestBuildHandler::ProcessHandler() // Remember start build time this->StartBuild = this->CTest->CurrentTime(); this->StartBuildTime = std::chrono::system_clock::now(); + + cmStringReplaceHelper colorRemover("\x1b\\[[0-9;]*m", "", nullptr); + this->ColorRemover = &colorRemover; int retVal = 0; int res = cmsysProcess_State_Exited; if (!this->CTest->GetShowOnly()) { @@ -572,8 +569,7 @@ void cmCTestBuildHandler::GenerateXMLLogScraped(cmXMLWriter& xml) std::string srcdir = this->CTest->GetCTestConfiguration("SourceDirectory"); // make sure the source dir is in the correct case on windows // via a call to collapse full path. - srcdir = cmSystemTools::CollapseFullPath(srcdir); - srcdir += "/"; + srcdir = cmStrCat(cmSystemTools::CollapseFullPath(srcdir), '/'); for (it = ew.begin(); it != ew.end() && (numErrorsAllowed || numWarningsAllowed); it++) { cmCTestBuildErrorWarning* cm = &(*it); @@ -704,10 +700,8 @@ cmCTestBuildHandler::LaunchHelper::LaunchHelper(cmCTestBuildHandler* handler) } else { // Compute a directory in which to store launcher fragments. std::string& launchDir = this->Handler->CTestLaunchDir; - launchDir = this->CTest->GetBinaryDir(); - launchDir += "/Testing/"; - launchDir += tag; - launchDir += "/Build"; + launchDir = + cmStrCat(this->CTest->GetBinaryDir(), "/Testing/", tag, "/Build"); // Clean out any existing launcher fragments. cmSystemTools::RemoveADirectory(launchDir); @@ -716,8 +710,7 @@ cmCTestBuildHandler::LaunchHelper::LaunchHelper(cmCTestBuildHandler* handler) // Enable launcher fragments. cmSystemTools::MakeDirectory(launchDir); this->WriteLauncherConfig(); - std::string launchEnv = "CTEST_LAUNCH_LOGS="; - launchEnv += launchDir; + std::string launchEnv = cmStrCat("CTEST_LAUNCH_LOGS=", launchDir); cmSystemTools::PutEnv(launchEnv); } } @@ -743,8 +736,8 @@ void cmCTestBuildHandler::LaunchHelper::WriteLauncherConfig() this->Handler->ReallyCustomWarningExceptions); // Give some testing configuration information to the launcher. - std::string fname = this->Handler->CTestLaunchDir; - fname += "/CTestLaunchConfig.cmake"; + std::string fname = + cmStrCat(this->Handler->CTestLaunchDir, "/CTestLaunchConfig.cmake"); cmGeneratedFileStream fout(fname); std::string srcdir = this->CTest->GetCTestConfiguration("SourceDirectory"); fout << "set(CTEST_SOURCE_DIRECTORY \"" << srcdir << "\")\n"; @@ -756,10 +749,8 @@ void cmCTestBuildHandler::LaunchHelper::WriteScrapeMatchers( if (matchers.empty()) { return; } - std::string fname = this->Handler->CTestLaunchDir; - fname += "/Custom"; - fname += purpose; - fname += ".txt"; + std::string fname = + cmStrCat(this->Handler->CTestLaunchDir, "/Custom", purpose, ".txt"); cmGeneratedFileStream fout(fname); for (std::string const& m : matchers) { fout << m << "\n"; @@ -898,9 +889,8 @@ int cmCTestBuildHandler::RunMakeCommand(const std::string& command, // dashboard. cmCTestBuildErrorWarning errorwarning; errorwarning.LogLine = 1; - errorwarning.Text = - "*** WARNING non-zero return value in ctest from: "; - errorwarning.Text += argv[0]; + errorwarning.Text = cmStrCat( + "*** WARNING non-zero return value in ctest from: ", argv[0]); errorwarning.PreContext.clear(); errorwarning.PostContext.clear(); errorwarning.Error = false; @@ -922,8 +912,8 @@ int cmCTestBuildHandler::RunMakeCommand(const std::string& command, // If there was an error running command, report that on the dashboard. cmCTestBuildErrorWarning errorwarning; errorwarning.LogLine = 1; - errorwarning.Text = "*** ERROR executing: "; - errorwarning.Text += cmsysProcess_GetErrorString(cp); + errorwarning.Text = + cmStrCat("*** ERROR executing: ", cmsysProcess_GetErrorString(cp)); errorwarning.PreContext.clear(); errorwarning.PostContext.clear(); errorwarning.Error = true; @@ -1084,7 +1074,12 @@ int cmCTestBuildHandler::ProcessSingleLine(const char* data) return b_REGULAR_LINE; } - cmCTestOptionalLog(this->CTest, DEBUG, "Line: [" << data << "]" << std::endl, + // Ignore ANSI color codes when checking for errors and warnings. + std::string input(data); + std::string line; + this->ColorRemover->Replace(input, line); + + cmCTestOptionalLog(this->CTest, DEBUG, "Line: [" << line << "]" << std::endl, this->Quiet); int warningLine = 0; @@ -1096,10 +1091,10 @@ int cmCTestBuildHandler::ProcessSingleLine(const char* data) // Errors int wrxCnt = 0; for (cmsys::RegularExpression& rx : this->ErrorMatchRegex) { - if (rx.find(data)) { + if (rx.find(line.c_str())) { errorLine = 1; cmCTestOptionalLog(this->CTest, DEBUG, - " Error Line: " << data << " (matches: " + " Error Line: " << line << " (matches: " << this->CustomErrorMatches[wrxCnt] << ")" << std::endl, this->Quiet); @@ -1110,11 +1105,11 @@ int cmCTestBuildHandler::ProcessSingleLine(const char* data) // Error exceptions wrxCnt = 0; for (cmsys::RegularExpression& rx : this->ErrorExceptionRegex) { - if (rx.find(data)) { + if (rx.find(line.c_str())) { errorLine = 0; cmCTestOptionalLog(this->CTest, DEBUG, " Not an error Line: " - << data << " (matches: " + << line << " (matches: " << this->CustomErrorExceptions[wrxCnt] << ")" << std::endl, this->Quiet); @@ -1127,11 +1122,11 @@ int cmCTestBuildHandler::ProcessSingleLine(const char* data) // Warnings int wrxCnt = 0; for (cmsys::RegularExpression& rx : this->WarningMatchRegex) { - if (rx.find(data)) { + if (rx.find(line.c_str())) { warningLine = 1; cmCTestOptionalLog(this->CTest, DEBUG, " Warning Line: " - << data << " (matches: " + << line << " (matches: " << this->CustomWarningMatches[wrxCnt] << ")" << std::endl, this->Quiet); @@ -1143,11 +1138,11 @@ int cmCTestBuildHandler::ProcessSingleLine(const char* data) wrxCnt = 0; // Warning exceptions for (cmsys::RegularExpression& rx : this->WarningExceptionRegex) { - if (rx.find(data)) { + if (rx.find(line.c_str())) { warningLine = 0; cmCTestOptionalLog(this->CTest, DEBUG, " Not a warning Line: " - << data << " (matches: " + << line << " (matches: " << this->CustomWarningExceptions[wrxCnt] << ")" << std::endl, this->Quiet); diff --git a/Source/CTest/cmCTestBuildHandler.h b/Source/CTest/cmCTestBuildHandler.h index 722c590..87f1534 100644 --- a/Source/CTest/cmCTestBuildHandler.h +++ b/Source/CTest/cmCTestBuildHandler.h @@ -18,6 +18,7 @@ #include <vector> class cmMakefile; +class cmStringReplaceHelper; class cmXMLWriter; /** \class cmCTestBuildHandler @@ -143,6 +144,9 @@ private: int MaxErrors; int MaxWarnings; + // Used to remove ANSI color codes before checking for errors and warnings. + cmStringReplaceHelper* ColorRemover; + bool UseCTestLaunch; std::string CTestLaunchDir; class LaunchHelper; diff --git a/Source/CTest/cmCTestCVS.cxx b/Source/CTest/cmCTestCVS.cxx index 9c03839..560c169 100644 --- a/Source/CTest/cmCTestCVS.cxx +++ b/Source/CTest/cmCTestCVS.cxx @@ -4,8 +4,10 @@ #include "cmCTest.h" #include "cmProcessTools.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmXMLWriter.h" +#include "cm_string_view.hxx" #include "cmsys/FStream.hxx" #include "cmsys/RegularExpression.hxx" @@ -204,8 +206,7 @@ std::string cmCTestCVS::ComputeBranchFlag(std::string const& dir) if (tagStream && cmSystemTools::GetLineFromStream(tagStream, tagLine) && tagLine.size() > 1 && tagLine[0] == 'T') { // Use the branch specified in the tag file. - std::string flag = "-r"; - flag += tagLine.substr(1); + std::string flag = cmStrCat("-r", cm::string_view(tagLine).substr(1)); return flag; } // Use the default branch. diff --git a/Source/CTest/cmCTestConfigureCommand.cxx b/Source/CTest/cmCTestConfigureCommand.cxx index 74a932a..320c184 100644 --- a/Source/CTest/cmCTestConfigureCommand.cxx +++ b/Source/CTest/cmCTestConfigureCommand.cxx @@ -6,6 +6,7 @@ #include "cmCTestConfigureHandler.h" #include "cmGlobalGenerator.h" #include "cmMakefile.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmake.h" @@ -25,7 +26,7 @@ cmCTestGenericHandler* cmCTestConfigureCommand::InitializeHandler() std::vector<std::string> options; if (this->Values[ctc_OPTIONS]) { - cmSystemTools::ExpandListArgument(this->Values[ctc_OPTIONS], options); + cmExpandList(this->Values[ctc_OPTIONS], options); } if (this->CTest->GetCTestConfiguration("BuildDirectory").empty()) { @@ -75,9 +76,8 @@ cmCTestGenericHandler* cmCTestConfigureCommand::InitializeHandler() delete gg; } - std::string cmakeConfigureCommand = "\""; - cmakeConfigureCommand += cmSystemTools::GetCMakeCommand(); - cmakeConfigureCommand += "\""; + std::string cmakeConfigureCommand = + cmStrCat('"', cmSystemTools::GetCMakeCommand(), '"'); for (std::string const& option : options) { cmakeConfigureCommand += " \""; diff --git a/Source/CTest/cmCTestConfigureCommand.h b/Source/CTest/cmCTestConfigureCommand.h index 0cbcbfa..4677c83 100644 --- a/Source/CTest/cmCTestConfigureCommand.h +++ b/Source/CTest/cmCTestConfigureCommand.h @@ -6,11 +6,14 @@ #include "cmConfigure.h" // IWYU pragma: keep #include "cmCTestHandlerCommand.h" +#include "cmCommand.h" #include <string> +#include <utility> + +#include "cm_memory.hxx" class cmCTestGenericHandler; -class cmCommand; /** \class cmCTestConfigure * \brief Run a ctest script @@ -25,12 +28,12 @@ public: /** * This is a virtual constructor for the command. */ - cmCommand* Clone() override + std::unique_ptr<cmCommand> Clone() override { - cmCTestConfigureCommand* ni = new cmCTestConfigureCommand; + auto ni = cm::make_unique<cmCTestConfigureCommand>(); ni->CTest = this->CTest; ni->CTestScriptHandler = this->CTestScriptHandler; - return ni; + return std::unique_ptr<cmCommand>(std::move(ni)); } /** diff --git a/Source/CTest/cmCTestCoverageCommand.h b/Source/CTest/cmCTestCoverageCommand.h index 1ae2d86..08f31f7 100644 --- a/Source/CTest/cmCTestCoverageCommand.h +++ b/Source/CTest/cmCTestCoverageCommand.h @@ -6,12 +6,15 @@ #include "cmConfigure.h" // IWYU pragma: keep #include "cmCTestHandlerCommand.h" +#include "cmCommand.h" #include <set> #include <string> +#include <utility> + +#include "cm_memory.hxx" class cmCTestGenericHandler; -class cmCommand; /** \class cmCTestCoverage * \brief Run a ctest script @@ -26,12 +29,12 @@ public: /** * This is a virtual constructor for the command. */ - cmCommand* Clone() override + std::unique_ptr<cmCommand> Clone() override { - cmCTestCoverageCommand* ni = new cmCTestCoverageCommand; + auto ni = cm::make_unique<cmCTestCoverageCommand>(); ni->CTest = this->CTest; ni->CTestScriptHandler = this->CTestScriptHandler; - return ni; + return std::unique_ptr<cmCommand>(std::move(ni)); } /** diff --git a/Source/CTest/cmCTestCoverageHandler.cxx b/Source/CTest/cmCTestCoverageHandler.cxx index f6028c4..772fa47 100644 --- a/Source/CTest/cmCTestCoverageHandler.cxx +++ b/Source/CTest/cmCTestCoverageHandler.cxx @@ -13,6 +13,7 @@ #include "cmParseGTMCoverage.h" #include "cmParseJacocoCoverage.h" #include "cmParsePHPCoverage.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmWorkingDirectory.h" #include "cmXMLWriter.h" @@ -129,10 +130,9 @@ void cmCTestCoverageHandler::Initialize() void cmCTestCoverageHandler::CleanCoverageLogFiles(std::ostream& log) { - std::string logGlob = this->CTest->GetCTestConfiguration("BuildDirectory"); - logGlob += "/Testing/"; - logGlob += this->CTest->GetCurrentTag(); - logGlob += "/CoverageLog*"; + std::string logGlob = + cmStrCat(this->CTest->GetCTestConfiguration("BuildDirectory"), "/Testing/", + this->CTest->GetCurrentTag(), "/CoverageLog*"); cmsys::Glob gl; gl.FindFiles(logGlob); std::vector<std::string> const& files = gl.GetFiles(); @@ -1181,7 +1181,7 @@ int cmCTestCoverageHandler::HandleGCovCoverage( // gcov 4.7 can have output lines saying "No executable lines" and // "Removing 'filename.gcov'"... Don't log those as "errors." if (line != "No executable lines" && - !cmSystemTools::StringStartsWith(line.c_str(), "Removing ")) { + !cmHasLiteralPrefix(line, "Removing ")) { cmCTestLog(this->CTest, ERROR_MESSAGE, "Unknown gcov output line: [" << line << "]" << std::endl); @@ -1455,8 +1455,7 @@ int cmCTestCoverageHandler::HandleLCovCoverage( std::vector<std::string> lcovFiles; dir = this->CTest->GetBinaryDir(); std::string daGlob; - daGlob = dir; - daGlob += "/*.LCOV"; + daGlob = cmStrCat(dir, "/*.LCOV"); cmCTestOptionalLog( this->CTest, HANDLER_VERBOSE_OUTPUT, " looking for LCOV files in: " << daGlob << std::endl, this->Quiet); @@ -1597,12 +1596,10 @@ void cmCTestCoverageHandler::FindGCovFiles(std::vector<std::string>& files) cmCTestOptionalLog( this->CTest, HANDLER_VERBOSE_OUTPUT, " globbing for coverage in: " << lm.first << std::endl, this->Quiet); - std::string daGlob = lm.first; - daGlob += "/*.da"; + std::string daGlob = cmStrCat(lm.first, "/*.da"); gl.FindFiles(daGlob); cmAppend(files, gl.GetFiles()); - daGlob = lm.first; - daGlob += "/*.gcda"; + daGlob = cmStrCat(lm.first, "/*.gcda"); gl.FindFiles(daGlob); cmAppend(files, gl.GetFiles()); } @@ -1631,8 +1628,7 @@ bool cmCTestCoverageHandler::FindLCovFiles(std::vector<std::string>& files) // DPI file should appear in build directory std::string daGlob; - daGlob = buildDir; - daGlob += "/*.dpi"; + daGlob = cmStrCat(buildDir, "/*.dpi"); cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " looking for dpi files in: " << daGlob << std::endl, this->Quiet); @@ -1945,10 +1941,9 @@ int cmCTestCoverageHandler::RunBullseyeCommand( cmCTestRunProcess runCoverageSrc; runCoverageSrc.SetCommand(program.c_str()); runCoverageSrc.AddArgument(arg); - std::string stdoutFile = cont->BinaryDir + "/Testing/Temporary/"; - stdoutFile += this->GetCTestInstance()->GetCurrentTag(); - stdoutFile += "-"; - stdoutFile += cmd; + std::string stdoutFile = + cmStrCat(cont->BinaryDir, "/Testing/Temporary/", + this->GetCTestInstance()->GetCurrentTag(), '-', cmd); std::string stderrFile = stdoutFile; stdoutFile += ".stdout"; stderrFile += ".stderr"; @@ -2037,9 +2032,7 @@ int cmCTestCoverageHandler::RunBullseyeSourceSummary( coveredFileNames.insert(file); if (!cmSystemTools::FileIsFullPath(sourceFile)) { // file will be relative to the binary dir - file = cont->BinaryDir; - file += "/"; - file += sourceFile; + file = cmStrCat(cont->BinaryDir, '/', sourceFile); } file = cmSystemTools::CollapseFullPath(file); bool shouldIDoCoverage = @@ -2221,9 +2214,8 @@ int cmCTestCoverageHandler::GetLabelId(std::string const& label) void cmCTestCoverageHandler::LoadLabels() { - std::string fileList = this->CTest->GetBinaryDir(); - fileList += "/CMakeFiles"; - fileList += "/TargetDirectories.txt"; + std::string fileList = + cmStrCat(this->CTest->GetBinaryDir(), "/CMakeFiles/TargetDirectories.txt"); cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " target directory list [" << fileList << "]\n", this->Quiet); @@ -2237,8 +2229,7 @@ void cmCTestCoverageHandler::LoadLabels() void cmCTestCoverageHandler::LoadLabels(const char* dir) { LabelSet& dirLabels = this->TargetDirs[dir]; - std::string fname = dir; - fname += "/Labels.txt"; + std::string fname = cmStrCat(dir, "/Labels.txt"); cmsys::ifstream fin(fname.c_str()); if (!fin) { return; diff --git a/Source/CTest/cmCTestCurl.cxx b/Source/CTest/cmCTestCurl.cxx index cc63e45..40f5918 100644 --- a/Source/CTest/cmCTestCurl.cxx +++ b/Source/CTest/cmCTestCurl.cxx @@ -5,6 +5,7 @@ #include "cmAlgorithms.h" #include "cmCTest.h" #include "cmCurl.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include <ostream> @@ -127,9 +128,7 @@ bool cmCTestCurl::UploadFile(std::string const& local_file, return false; } // set the url - std::string upload_url = url; - upload_url += "?"; - upload_url += fields; + std::string upload_url = cmStrCat(url, '?', fields); ::curl_easy_setopt(this->Curl, CURLOPT_URL, upload_url.c_str()); // now specify which file to upload ::curl_easy_setopt(this->Curl, CURLOPT_INFILE, ftpfile); diff --git a/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.h b/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.h index 9425ece..84250cb 100644 --- a/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.h +++ b/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.h @@ -6,11 +6,14 @@ #include "cmConfigure.h" // IWYU pragma: keep #include "cmCTestCommand.h" +#include "cmCommand.h" #include <string> +#include <utility> #include <vector> -class cmCommand; +#include "cm_memory.hxx" + class cmExecutionStatus; /** \class cmCTestEmptyBinaryDirectory @@ -27,13 +30,12 @@ public: /** * This is a virtual constructor for the command. */ - cmCommand* Clone() override + std::unique_ptr<cmCommand> Clone() override { - cmCTestEmptyBinaryDirectoryCommand* ni = - new cmCTestEmptyBinaryDirectoryCommand; + auto ni = cm::make_unique<cmCTestEmptyBinaryDirectoryCommand>(); ni->CTest = this->CTest; ni->CTestScriptHandler = this->CTestScriptHandler; - return ni; + return std::unique_ptr<cmCommand>(std::move(ni)); } /** diff --git a/Source/CTest/cmCTestGIT.cxx b/Source/CTest/cmCTestGIT.cxx index 9d9761c..f7319ef 100644 --- a/Source/CTest/cmCTestGIT.cxx +++ b/Source/CTest/cmCTestGIT.cxx @@ -10,11 +10,11 @@ #include <time.h> #include <vector> -#include "cmAlgorithms.h" #include "cmCTest.h" #include "cmCTestVC.h" #include "cmProcessOutput.h" #include "cmProcessTools.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" static unsigned int cmCTestGITVersion(unsigned int epic, unsigned int major, @@ -111,8 +111,8 @@ std::string cmCTestGIT::FindGitDir() else if (git_dir[0] == '/') { // Cygwin Git reports a full path that Cygwin understands, but we // are a Windows application. Run "cygpath" to get Windows path. - std::string cygpath_exe = cmSystemTools::GetFilenamePath(git); - cygpath_exe += "/cygpath.exe"; + std::string cygpath_exe = + cmStrCat(cmSystemTools::GetFilenamePath(git), "/cygpath.exe"); if (cmSystemTools::FileExists(cygpath_exe)) { char const* cygpath[] = { cygpath_exe.c_str(), "-w", git_dir.c_str(), 0 }; @@ -211,8 +211,7 @@ bool cmCTestGIT::UpdateByFetchAndReset() bool cmCTestGIT::UpdateByCustom(std::string const& custom) { - std::vector<std::string> git_custom_command; - cmSystemTools::ExpandListArgument(custom, git_custom_command, true); + std::vector<std::string> git_custom_command = cmExpandedList(custom, true); std::vector<char const*> git_custom; git_custom.reserve(git_custom_command.size() + 1); for (std::string const& i : git_custom_command) { @@ -270,7 +269,7 @@ bool cmCTestGIT::UpdateImpl() std::string init_submodules = this->CTest->GetCTestConfiguration("GITInitSubmodules"); - if (cmSystemTools::IsOn(init_submodules)) { + if (cmIsOn(init_submodules)) { char const* git_submodule_init[] = { git, "submodule", "init", nullptr }; ret = this->RunChild(git_submodule_init, &submodule_out, &submodule_err, top_dir.c_str()); diff --git a/Source/CTest/cmCTestHandlerCommand.cxx b/Source/CTest/cmCTestHandlerCommand.cxx index adf9553..6add717 100644 --- a/Source/CTest/cmCTestHandlerCommand.cxx +++ b/Source/CTest/cmCTestHandlerCommand.cxx @@ -4,6 +4,7 @@ #include "cmCTest.h" #include "cmCTestGenericHandler.h" +#include "cmExecutionStatus.h" #include "cmMakefile.h" #include "cmMessageType.h" #include "cmSystemTools.h" @@ -13,8 +14,6 @@ #include <sstream> #include <stdlib.h> -class cmExecutionStatus; - cmCTestHandlerCommand::cmCTestHandlerCommand() { const size_t INIT_SIZE = 100; @@ -86,7 +85,7 @@ private: } bool cmCTestHandlerCommand::InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& /*unused*/) + cmExecutionStatus& status) { // save error state and restore it if needed SaveRestoreErrorState errorState; @@ -113,20 +112,20 @@ bool cmCTestHandlerCommand::InitialPass(std::vector<std::string> const& args, foundBadArgument = true; } } - bool capureCMakeError = (this->Values[ct_CAPTURE_CMAKE_ERROR] && - *this->Values[ct_CAPTURE_CMAKE_ERROR]); + bool captureCMakeError = (this->Values[ct_CAPTURE_CMAKE_ERROR] && + *this->Values[ct_CAPTURE_CMAKE_ERROR]); // now that arguments are parsed check to see if there is a // CAPTURE_CMAKE_ERROR specified let the errorState object know. - if (capureCMakeError) { + if (captureCMakeError) { errorState.CaptureCMakeError(); } // if we found a bad argument then exit before running command if (foundBadArgument) { // store the cmake error - if (capureCMakeError) { + if (captureCMakeError) { this->Makefile->AddDefinition(this->Values[ct_CAPTURE_CMAKE_ERROR], "-1"); - std::string const err = this->GetName() + " " + this->GetError(); + std::string const err = this->GetName() + " " + status.GetError(); if (!cmSystemTools::FindLastString(err.c_str(), "unknown error.")) { cmCTestLog(this->CTest, ERROR_MESSAGE, err << " error from command\n"); } @@ -192,11 +191,11 @@ bool cmCTestHandlerCommand::InitialPass(std::vector<std::string> const& args, cmCTestLog(this->CTest, ERROR_MESSAGE, "Cannot instantiate test handler " << this->GetName() << std::endl); - if (capureCMakeError) { + if (captureCMakeError) { this->Makefile->AddDefinition(this->Values[ct_CAPTURE_CMAKE_ERROR], "-1"); - const char* err = this->GetError(); - if (err && !cmSystemTools::FindLastString(err, "unknown error.")) { + std::string const& err = status.GetError(); + if (!cmSystemTools::FindLastString(err.c_str(), "unknown error.")) { cmCTestLog(this->CTest, ERROR_MESSAGE, err << " error from command\n"); } return true; @@ -216,11 +215,11 @@ bool cmCTestHandlerCommand::InitialPass(std::vector<std::string> const& args, this->SetError("failed to change directory to " + this->CTest->GetCTestConfiguration("BuildDirectory") + " : " + std::strerror(workdir.GetLastResult())); - if (capureCMakeError) { + if (captureCMakeError) { this->Makefile->AddDefinition(this->Values[ct_CAPTURE_CMAKE_ERROR], "-1"); cmCTestLog(this->CTest, ERROR_MESSAGE, - this->GetName() << " " << this->GetError() << "\n"); + this->GetName() << " " << status.GetError() << "\n"); // return success because failure is recorded in CAPTURE_CMAKE_ERROR return true; } @@ -229,21 +228,19 @@ bool cmCTestHandlerCommand::InitialPass(std::vector<std::string> const& args, int res = handler->ProcessHandler(); if (this->Values[ct_RETURN_VALUE] && *this->Values[ct_RETURN_VALUE]) { - std::ostringstream str; - str << res; this->Makefile->AddDefinition(this->Values[ct_RETURN_VALUE], - str.str().c_str()); + std::to_string(res)); } this->ProcessAdditionalValues(handler); // log the error message if there was an error - if (capureCMakeError) { + if (captureCMakeError) { const char* returnString = "0"; if (cmSystemTools::GetErrorOccuredFlag()) { returnString = "-1"; - const char* err = this->GetError(); + std::string const& err = status.GetError(); // print out the error if it is not "unknown error" which means // there was no message - if (err && !cmSystemTools::FindLastString(err, "unknown error.")) { + if (!cmSystemTools::FindLastString(err.c_str(), "unknown error.")) { cmCTestLog(this->CTest, ERROR_MESSAGE, err); } } diff --git a/Source/CTest/cmCTestLaunch.cxx b/Source/CTest/cmCTestLaunch.cxx index a96513e..ac52581 100644 --- a/Source/CTest/cmCTestLaunch.cxx +++ b/Source/CTest/cmCTestLaunch.cxx @@ -6,7 +6,6 @@ #include "cmsys/Process.h" #include "cmsys/RegularExpression.hxx" #include <iostream> -#include <memory> // IWYU pragma: keep #include <stdlib.h> #include <string.h> @@ -17,6 +16,7 @@ #include "cmProcessOutput.h" #include "cmState.h" #include "cmStateSnapshot.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmXMLWriter.h" #include "cmake.h" @@ -176,14 +176,8 @@ void cmCTestLaunch::ComputeFileNames() this->LogHash = md5.FinalizeHex(); // We store stdout and stderr in temporary log files. - this->LogOut = this->LogDir; - this->LogOut += "launch-"; - this->LogOut += this->LogHash; - this->LogOut += "-out.txt"; - this->LogErr = this->LogDir; - this->LogErr += "launch-"; - this->LogErr += this->LogHash; - this->LogErr += "-err.txt"; + this->LogOut = cmStrCat(this->LogDir, "launch-", this->LogHash, "-out.txt"); + this->LogErr = cmStrCat(this->LogDir, "launch-", this->LogHash, "-err.txt"); } void cmCTestLaunch::RunChild() @@ -282,11 +276,8 @@ void cmCTestLaunch::LoadLabels() } // Labels are listed in per-target files. - std::string fname = this->OptionBuildDir; - fname += "/CMakeFiles"; - fname += "/"; - fname += this->OptionTargetName; - fname += ".dir/Labels.txt"; + std::string fname = cmStrCat(this->OptionBuildDir, "/CMakeFiles/", + this->OptionTargetName, ".dir/Labels.txt"); // We are interested in per-target labels for this source file. std::string source = this->OptionSource; @@ -340,10 +331,9 @@ bool cmCTestLaunch::IsError() const void cmCTestLaunch::WriteXML() { // Name the xml file. - std::string logXML = this->LogDir; - logXML += this->IsError() ? "error-" : "warning-"; - logXML += this->LogHash; - logXML += ".xml"; + std::string logXML = + cmStrCat(this->LogDir, this->IsError() ? "error-" : "warning-", + this->LogHash, ".xml"); // Use cmGeneratedFileStream to atomically create the report file. cmGeneratedFileStream fxml(logXML); @@ -494,9 +484,9 @@ void cmCTestLaunch::DumpFileToXML(cmXMLElement& e3, const char* tag, continue; } if (this->Match(line, this->RegexWarningSuppress)) { - line = "[CTest: warning suppressed] " + line; + line = cmStrCat("[CTest: warning suppressed] ", line); } else if (this->Match(line, this->RegexWarning)) { - line = "[CTest: warning matched] " + line; + line = cmStrCat("[CTest: warning matched] ", line); } e4.Content(sep); e4.Content(line); @@ -546,10 +536,7 @@ void cmCTestLaunch::LoadScrapeRules() void cmCTestLaunch::LoadScrapeRules( const char* purpose, std::vector<cmsys::RegularExpression>& regexps) { - std::string fname = this->LogDir; - fname += "Custom"; - fname += purpose; - fname += ".txt"; + std::string fname = cmStrCat(this->LogDir, "Custom", purpose, ".txt"); cmsys::ifstream fin(fname.c_str(), std::ios::in | std::ios::binary); std::string line; cmsys::RegularExpression rex; @@ -595,7 +582,7 @@ bool cmCTestLaunch::Match(std::string const& line, bool cmCTestLaunch::MatchesFilterPrefix(std::string const& line) const { return !this->OptionFilterPrefix.empty() && - cmSystemTools::StringStartsWith(line, this->OptionFilterPrefix.c_str()); + cmHasPrefix(line, this->OptionFilterPrefix); } int cmCTestLaunch::Main(int argc, const char* const argv[]) @@ -617,8 +604,7 @@ void cmCTestLaunch::LoadConfig() cm.GetCurrentSnapshot().SetDefaultDefinitions(); cmGlobalGenerator gg(&cm); cmMakefile mf(&gg, cm.GetCurrentSnapshot()); - std::string fname = this->LogDir; - fname += "CTestLaunchConfig.cmake"; + std::string fname = cmStrCat(this->LogDir, "CTestLaunchConfig.cmake"); if (cmSystemTools::FileExists(fname) && mf.ReadListFile(fname)) { this->SourceDir = mf.GetSafeDefinition("CTEST_SOURCE_DIRECTORY"); cmSystemTools::ConvertToUnixSlashes(this->SourceDir); diff --git a/Source/CTest/cmCTestMemCheckCommand.cxx b/Source/CTest/cmCTestMemCheckCommand.cxx index 7dad1ce..804efa5 100644 --- a/Source/CTest/cmCTestMemCheckCommand.cxx +++ b/Source/CTest/cmCTestMemCheckCommand.cxx @@ -2,7 +2,6 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmCTestMemCheckCommand.h" -#include <sstream> #include <string> #include <vector> @@ -45,9 +44,9 @@ void cmCTestMemCheckCommand::ProcessAdditionalValues( cmCTestGenericHandler* handler) { if (this->Values[ctm_DEFECT_COUNT] && *this->Values[ctm_DEFECT_COUNT]) { - std::ostringstream str; - str << static_cast<cmCTestMemCheckHandler*>(handler)->GetDefectCount(); - this->Makefile->AddDefinition(this->Values[ctm_DEFECT_COUNT], - str.str().c_str()); + this->Makefile->AddDefinition( + this->Values[ctm_DEFECT_COUNT], + std::to_string( + static_cast<cmCTestMemCheckHandler*>(handler)->GetDefectCount())); } } diff --git a/Source/CTest/cmCTestMemCheckCommand.h b/Source/CTest/cmCTestMemCheckCommand.h index b6b3c40..837a687 100644 --- a/Source/CTest/cmCTestMemCheckCommand.h +++ b/Source/CTest/cmCTestMemCheckCommand.h @@ -5,10 +5,14 @@ #include "cmConfigure.h" // IWYU pragma: keep +#include <utility> + +#include "cm_memory.hxx" + #include "cmCTestTestCommand.h" +#include "cmCommand.h" class cmCTestGenericHandler; -class cmCommand; /** \class cmCTestMemCheck * \brief Run a ctest script @@ -23,12 +27,12 @@ public: /** * This is a virtual constructor for the command. */ - cmCommand* Clone() override + std::unique_ptr<cmCommand> Clone() override { - cmCTestMemCheckCommand* ni = new cmCTestMemCheckCommand; + auto ni = cm::make_unique<cmCTestMemCheckCommand>(); ni->CTest = this->CTest; ni->CTestScriptHandler = this->CTestScriptHandler; - return ni; + return std::unique_ptr<cmCommand>(std::move(ni)); } protected: diff --git a/Source/CTest/cmCTestMemCheckHandler.cxx b/Source/CTest/cmCTestMemCheckHandler.cxx index b09e7bb..259240f 100644 --- a/Source/CTest/cmCTestMemCheckHandler.cxx +++ b/Source/CTest/cmCTestMemCheckHandler.cxx @@ -1074,10 +1074,7 @@ void cmCTestMemCheckHandler::AppendMemTesterOutput(cmCTestTestResult& res, void cmCTestMemCheckHandler::TestOutputFileNames( int test, std::vector<std::string>& files) { - std::string index; - std::ostringstream stream; - stream << test; - index = stream.str(); + std::string index = std::to_string(test); std::string ofile = this->MemoryTesterOutputFile; std::string::size_type pos = ofile.find("??"); ofile.replace(pos, 2, index); diff --git a/Source/CTest/cmCTestMultiProcessHandler.cxx b/Source/CTest/cmCTestMultiProcessHandler.cxx index ef63073..af1980a 100644 --- a/Source/CTest/cmCTestMultiProcessHandler.cxx +++ b/Source/CTest/cmCTestMultiProcessHandler.cxx @@ -10,6 +10,7 @@ #include "cmDuration.h" #include "cmListFileCache.h" #include "cmRange.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmWorkingDirectory.h" @@ -29,11 +30,13 @@ #include <iostream> #include <list> #include <math.h> +#include <memory> #include <sstream> #include <stack> #include <stdlib.h> #include <unordered_map> #include <utility> +#include <vector> namespace cmsys { class RegularExpression; @@ -108,8 +111,7 @@ void cmCTestMultiProcessHandler::SetTestLoad(unsigned long load) std::string fake_load_value; if (cmSystemTools::GetEnv("__CTEST_FAKE_LOAD_AVERAGE_FOR_TESTING", fake_load_value)) { - if (!cmSystemTools::StringToULong(fake_load_value.c_str(), - &this->FakeLoadForTesting)) { + if (!cmStrToULong(fake_load_value, &this->FakeLoadForTesting)) { cmSystemTools::Error("Failed to parse fake load value: " + fake_load_value); } @@ -171,8 +173,7 @@ bool cmCTestMultiProcessHandler::StartTestProcess(int test) // Find any failed dependencies for this test. We assume the more common // scenario has no failed tests, so make it the outer loop. for (std::string const& f : *this->Failed) { - if (this->Properties[test]->RequireSuccessDepends.find(f) != - this->Properties[test]->RequireSuccessDepends.end()) { + if (cmContains(this->Properties[test]->RequireSuccessDepends, f)) { testRun->AddFailedDependency(f); } } @@ -188,10 +189,13 @@ bool cmCTestMultiProcessHandler::StartTestProcess(int test) std::strerror(workdir.GetLastResult())); } else { if (testRun->StartTest(this->Completed, this->Total)) { + // Ownership of 'testRun' has moved to another structure. + // When the test finishes, FinishTestProcess will be called. return true; } } + // Pass ownership of 'testRun'. this->FinishTestProcess(testRun, false); return false; } @@ -273,7 +277,7 @@ bool cmCTestMultiProcessHandler::StartTest(int test) { // Check for locked resources for (std::string const& i : this->Properties[test]->LockedResources) { - if (this->LockedResources.find(i) != this->LockedResources.end()) { + if (cmContains(this->LockedResources, i)) { return false; } } @@ -619,9 +623,7 @@ void cmCTestMultiProcessHandler::CreateParallelTestCostList() // In parallel test runs add previously failed tests to the front // of the cost list and queue other tests for further sorting for (auto const& t : this->Tests) { - if (std::find(this->LastTestsFailed.begin(), this->LastTestsFailed.end(), - this->Properties[t.first]->Name) != - this->LastTestsFailed.end()) { + if (cmContains(this->LastTestsFailed, this->Properties[t.first]->Name)) { // If the test failed last time, it should be run first. this->SortedTests.push_back(t.first); alreadySortedTests.insert(t.first); @@ -660,7 +662,7 @@ void cmCTestMultiProcessHandler::CreateParallelTestCostList() TestComparator(this)); for (auto const& j : sortedCopy) { - if (alreadySortedTests.find(j) == alreadySortedTests.end()) { + if (!cmContains(alreadySortedTests, j)) { this->SortedTests.push_back(j); alreadySortedTests.insert(j); } @@ -692,7 +694,7 @@ void cmCTestMultiProcessHandler::CreateSerialTestCostList() TestSet alreadySortedTests; for (int test : presortedList) { - if (alreadySortedTests.find(test) != alreadySortedTests.end()) { + if (cmContains(alreadySortedTests, test)) { continue; } @@ -700,8 +702,7 @@ void cmCTestMultiProcessHandler::CreateSerialTestCostList() GetAllTestDependencies(test, dependencies); for (int testDependency : dependencies) { - if (alreadySortedTests.find(testDependency) == - alreadySortedTests.end()) { + if (!cmContains(alreadySortedTests, testDependency)) { alreadySortedTests.insert(testDependency); this->SortedTests.push_back(testDependency); } @@ -821,6 +822,11 @@ static Json::Value DumpCTestProperties( "FAIL_REGULAR_EXPRESSION", DumpRegExToJsonArray(testProperties.ErrorRegularExpressions))); } + if (!testProperties.SkipRegularExpressions.empty()) { + properties.append(DumpCTestProperty( + "SKIP_REGULAR_EXPRESSION", + DumpRegExToJsonArray(testProperties.SkipRegularExpressions))); + } if (!testProperties.FixturesCleanup.empty()) { properties.append(DumpCTestProperty( "FIXTURES_CLEANUP", DumpToJsonArray(testProperties.FixturesCleanup))); @@ -855,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 2eb8dba..64354e8 100644 --- a/Source/CTest/cmCTestP4.cxx +++ b/Source/CTest/cmCTestP4.cxx @@ -7,6 +7,7 @@ #include "cmCTestVC.h" #include "cmProcessTools.h" #include "cmRange.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmsys/RegularExpression.hxx" @@ -459,8 +460,7 @@ bool cmCTestP4::LoadModifications() bool cmCTestP4::UpdateCustom(const std::string& custom) { - std::vector<std::string> p4_custom_command; - cmSystemTools::ExpandListArgument(custom, p4_custom_command, true); + std::vector<std::string> p4_custom_command = cmExpandedList(custom, true); std::vector<char const*> p4_custom; p4_custom.reserve(p4_custom_command.size() + 1); diff --git a/Source/CTest/cmCTestReadCustomFilesCommand.h b/Source/CTest/cmCTestReadCustomFilesCommand.h index ba25c51..db2ac5e 100644 --- a/Source/CTest/cmCTestReadCustomFilesCommand.h +++ b/Source/CTest/cmCTestReadCustomFilesCommand.h @@ -6,11 +6,14 @@ #include "cmConfigure.h" // IWYU pragma: keep #include "cmCTestCommand.h" +#include "cmCommand.h" #include <string> +#include <utility> #include <vector> -class cmCommand; +#include "cm_memory.hxx" + class cmExecutionStatus; /** \class cmCTestReadCustomFiles @@ -27,11 +30,11 @@ public: /** * This is a virtual constructor for the command. */ - cmCommand* Clone() override + std::unique_ptr<cmCommand> Clone() override { - cmCTestReadCustomFilesCommand* ni = new cmCTestReadCustomFilesCommand; + auto ni = cm::make_unique<cmCTestReadCustomFilesCommand>(); ni->CTest = this->CTest; - return ni; + return std::unique_ptr<cmCommand>(std::move(ni)); } /** diff --git a/Source/CTest/cmCTestRunScriptCommand.cxx b/Source/CTest/cmCTestRunScriptCommand.cxx index a7e47d3..f59ca57 100644 --- a/Source/CTest/cmCTestRunScriptCommand.cxx +++ b/Source/CTest/cmCTestRunScriptCommand.cxx @@ -5,8 +5,6 @@ #include "cmCTestScriptHandler.h" #include "cmMakefile.h" -#include <sstream> - class cmExecutionStatus; bool cmCTestRunScriptCommand::InitialPass(std::vector<std::string> const& args, @@ -41,9 +39,7 @@ bool cmCTestRunScriptCommand::InitialPass(std::vector<std::string> const& args, int ret; cmCTestScriptHandler::RunScript(this->CTest, this->Makefile, args[i].c_str(), !np, &ret); - std::ostringstream str; - str << ret; - this->Makefile->AddDefinition(returnVariable, str.str().c_str()); + this->Makefile->AddDefinition(returnVariable, std::to_string(ret)); } } return true; diff --git a/Source/CTest/cmCTestRunScriptCommand.h b/Source/CTest/cmCTestRunScriptCommand.h index 9d8b4b5..6961f6e 100644 --- a/Source/CTest/cmCTestRunScriptCommand.h +++ b/Source/CTest/cmCTestRunScriptCommand.h @@ -6,11 +6,14 @@ #include "cmConfigure.h" // IWYU pragma: keep #include "cmCTestCommand.h" +#include "cmCommand.h" #include <string> +#include <utility> #include <vector> -class cmCommand; +#include "cm_memory.hxx" + class cmExecutionStatus; /** \class cmCTestRunScript @@ -27,12 +30,12 @@ public: /** * This is a virtual constructor for the command. */ - cmCommand* Clone() override + std::unique_ptr<cmCommand> Clone() override { - cmCTestRunScriptCommand* ni = new cmCTestRunScriptCommand; + auto ni = cm::make_unique<cmCTestRunScriptCommand>(); ni->CTest = this->CTest; ni->CTestScriptHandler = this->CTestScriptHandler; - return ni; + return std::unique_ptr<cmCommand>(std::move(ni)); } /** diff --git a/Source/CTest/cmCTestRunTest.cxx b/Source/CTest/cmCTestRunTest.cxx index 31976b9..23c6b0d 100644 --- a/Source/CTest/cmCTestRunTest.cxx +++ b/Source/CTest/cmCTestRunTest.cxx @@ -6,12 +6,12 @@ #include "cmCTestMemCheckHandler.h" #include "cmCTestMultiProcessHandler.h" #include "cmProcess.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmWorkingDirectory.h" #include "cmsys/RegularExpression.hxx" #include <chrono> -#include <cmAlgorithms.h> #include <cstdint> #include <cstring> #include <iomanip> @@ -20,6 +20,8 @@ #include <stdio.h> #include <utility> +#include "cm_memory.hxx" + cmCTestRunTest::cmCTestRunTest(cmCTestMultiProcessHandler& multiHandler) : MultiTestHandler(multiHandler) { @@ -76,6 +78,7 @@ bool cmCTestRunTest::EndTest(size_t completed, size_t total, bool started) } std::int64_t retVal = this->TestProcess->GetExitValue(); bool forceFail = false; + bool forceSkip = false; bool skipped = false; bool outputTestErrorsToConsole = false; if (!this->TestProperties->RequiredRegularExpressions.empty() && @@ -84,49 +87,62 @@ bool cmCTestRunTest::EndTest(size_t completed, size_t total, bool started) for (auto& pass : this->TestProperties->RequiredRegularExpressions) { if (pass.first.find(this->ProcessOutput)) { found = true; - reason = "Required regular expression found."; + reason = cmStrCat("Required regular expression found. Regex=[", + pass.second, ']'); break; } } if (!found) { - reason = "Required regular expression not found."; + reason = "Required regular expression not found. Regex=["; + for (auto& pass : this->TestProperties->RequiredRegularExpressions) { + reason += pass.second; + reason += "\n"; + } + reason += "]"; forceFail = true; } - reason += "Regex=["; - for (auto& pass : this->TestProperties->RequiredRegularExpressions) { - reason += pass.second; - reason += "\n"; - } - reason += "]"; } if (!this->TestProperties->ErrorRegularExpressions.empty() && this->FailedDependencies.empty()) { - for (auto& pass : this->TestProperties->ErrorRegularExpressions) { - if (pass.first.find(this->ProcessOutput)) { - reason = "Error regular expression found in output."; - reason += " Regex=["; - reason += pass.second; - reason += "]"; + for (auto& fail : this->TestProperties->ErrorRegularExpressions) { + if (fail.first.find(this->ProcessOutput)) { + reason = cmStrCat("Error regular expression found in output. Regex=[", + fail.second, ']'); forceFail = true; break; } } } + if (!this->TestProperties->SkipRegularExpressions.empty() && + this->FailedDependencies.empty()) { + for (auto& skip : this->TestProperties->SkipRegularExpressions) { + if (skip.first.find(this->ProcessOutput)) { + reason = cmStrCat("Skip regular expression found in output. Regex=[", + skip.second, ']'); + forceSkip = true; + break; + } + } + } std::ostringstream outputStream; if (res == cmProcess::State::Exited) { bool success = !forceFail && (retVal == 0 || !this->TestProperties->RequiredRegularExpressions.empty()); - if (this->TestProperties->SkipReturnCode >= 0 && - this->TestProperties->SkipReturnCode == retVal) { + if ((this->TestProperties->SkipReturnCode >= 0 && + this->TestProperties->SkipReturnCode == retVal) || + forceSkip) { this->TestResult.Status = cmCTestTestHandler::NOT_RUN; std::ostringstream s; - s << "SKIP_RETURN_CODE=" << this->TestProperties->SkipReturnCode; + if (forceSkip) { + s << "SKIP_REGULAR_EXPRESSION_MATCHED"; + } else { + s << "SKIP_RETURN_CODE=" << this->TestProperties->SkipReturnCode; + } this->TestResult.CompletionStatus = s.str(); cmCTestLog(this->CTest, HANDLER_OUTPUT, "***Skipped "); skipped = true; - } else if ((success && !this->TestProperties->WillFail) || - (!success && this->TestProperties->WillFail)) { + } else if (success != this->TestProperties->WillFail) { this->TestResult.Status = cmCTestTestHandler::COMPLETED; outputStream << " Passed "; } else { @@ -481,12 +497,11 @@ bool cmCTestRunTest::StartTest(size_t completed, size_t total) this->TestProcess = cm::make_unique<cmProcess>(*this); std::string msg; if (this->CTest->GetConfigType().empty()) { - msg = "Test not available without configuration."; - msg += " (Missing \"-C <config>\"?)"; + msg = "Test not available without configuration. (Missing \"-C " + "<config>\"?)"; } else { - msg = "Test not available in configuration \""; - msg += this->CTest->GetConfigType(); - msg += "\"."; + msg = cmStrCat("Test not available in configuration \"", + this->CTest->GetConfigType(), "\"."); } *this->TestHandler->LogFile << msg << std::endl; cmCTestLog(this->CTest, ERROR_MESSAGE, msg << std::endl); @@ -666,7 +681,7 @@ bool cmCTestRunTest::ForkProcess(cmDuration testTimeOut, bool explicitTimeout, this->TestProcess->SetTimeout(timeout); -#ifdef CMAKE_BUILD_WITH_CMAKE +#ifndef CMAKE_BOOTSTRAP cmSystemTools::SaveRestoreEnvironment sre; #endif diff --git a/Source/CTest/cmCTestRunTest.h b/Source/CTest/cmCTestRunTest.h index 38cc417..43dfe8e 100644 --- a/Source/CTest/cmCTestRunTest.h +++ b/Source/CTest/cmCTestRunTest.h @@ -5,6 +5,7 @@ #include "cmConfigure.h" // IWYU pragma: keep +#include <memory> #include <set> #include <stddef.h> #include <string> @@ -12,7 +13,7 @@ #include "cmCTestTestHandler.h" #include "cmDuration.h" -#include "cmProcess.h" // IWYU pragma: keep (for unique_ptr) +#include "cmProcess.h" class cmCTest; class cmCTestMultiProcessHandler; diff --git a/Source/CTest/cmCTestSVN.cxx b/Source/CTest/cmCTestSVN.cxx index c834686..dc1472b 100644 --- a/Source/CTest/cmCTestSVN.cxx +++ b/Source/CTest/cmCTestSVN.cxx @@ -6,6 +6,7 @@ #include "cmCTest.h" #include "cmCTestVC.h" #include "cmProcessTools.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmXMLParser.h" #include "cmXMLWriter.h" @@ -143,9 +144,8 @@ bool cmCTestSVN::NoteNewRevision() // the repository root. if (!svninfo.Root.empty() && cmCTestSVNPathStarts(svninfo.URL, svninfo.Root)) { - svninfo.Base = - cmCTest::DecodeURL(svninfo.URL.substr(svninfo.Root.size())); - svninfo.Base += "/"; + svninfo.Base = cmStrCat( + cmCTest::DecodeURL(svninfo.URL.substr(svninfo.Root.size())), '/'); } this->Log << "Repository '" << svninfo.LocalPath << "' Base = " << svninfo.Base << "\n"; diff --git a/Source/CTest/cmCTestScriptHandler.cxx b/Source/CTest/cmCTestScriptHandler.cxx index a739f44..81966dd 100644 --- a/Source/CTest/cmCTestScriptHandler.cxx +++ b/Source/CTest/cmCTestScriptHandler.cxx @@ -4,13 +4,8 @@ #include "cmsys/Directory.hxx" #include "cmsys/Process.h" -#include <map> -#include <ratio> -#include <sstream> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <utility> + +#include "cm_memory.hxx" #include "cmCTest.h" #include "cmCTestBuildCommand.h" @@ -27,49 +22,35 @@ #include "cmCTestTestCommand.h" #include "cmCTestUpdateCommand.h" #include "cmCTestUploadCommand.h" +#include "cmCommand.h" #include "cmDuration.h" -#include "cmFunctionBlocker.h" #include "cmGeneratedFileStream.h" #include "cmGlobalGenerator.h" #include "cmMakefile.h" #include "cmState.h" #include "cmStateDirectory.h" #include "cmStateSnapshot.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmake.h" +#include <map> +#include <memory> +#include <ratio> +#include <sstream> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <utility> + #ifdef _WIN32 # include <windows.h> #else # include <unistd.h> #endif -class cmExecutionStatus; -struct cmListFileFunction; - #define CTEST_INITIAL_CMAKE_OUTPUT_FILE_NAME "CTestInitialCMakeOutput.log" -// used to keep elapsed time up to date -class cmCTestScriptFunctionBlocker : public cmFunctionBlocker -{ -public: - bool IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile& mf, - cmExecutionStatus& /*status*/) override; - // virtual bool ShouldRemove(const cmListFileFunction& lff, cmMakefile &mf); - // virtual void ScopeEnded(cmMakefile &mf); - - cmCTestScriptHandler* CTestScriptHandler; -}; - -// simply update the time and don't block anything -bool cmCTestScriptFunctionBlocker::IsFunctionBlocked( - const cmListFileFunction& /*lff*/, cmMakefile& /*mf*/, - cmExecutionStatus& /*status*/) -{ - this->CTestScriptHandler->UpdateElapsedTime(); - return false; -} - cmCTestScriptHandler::cmCTestScriptHandler() { this->Backup = false; @@ -163,16 +144,16 @@ void cmCTestScriptHandler::UpdateElapsedTime() auto itime = cmDurationTo<unsigned int>(std::chrono::steady_clock::now() - this->ScriptStartTime); auto timeString = std::to_string(itime); - this->Makefile->AddDefinition("CTEST_ELAPSED_TIME", timeString.c_str()); + this->Makefile->AddDefinition("CTEST_ELAPSED_TIME", timeString); } } -void cmCTestScriptHandler::AddCTestCommand(std::string const& name, - cmCTestCommand* command) +void cmCTestScriptHandler::AddCTestCommand( + std::string const& name, std::unique_ptr<cmCTestCommand> command) { command->CTest = this->CTest; command->CTestScriptHandler = this; - this->CMake->GetState()->AddBuiltinCommand(name, command); + this->CMake->GetState()->AddBuiltinCommand(name, std::move(command)); } int cmCTestScriptHandler::ExecuteScript(const std::string& total_script_arg) @@ -295,21 +276,28 @@ void cmCTestScriptHandler::CreateCMake() } }); - this->AddCTestCommand("ctest_build", new cmCTestBuildCommand); - this->AddCTestCommand("ctest_configure", new cmCTestConfigureCommand); - this->AddCTestCommand("ctest_coverage", new cmCTestCoverageCommand); + this->AddCTestCommand("ctest_build", cm::make_unique<cmCTestBuildCommand>()); + this->AddCTestCommand("ctest_configure", + cm::make_unique<cmCTestConfigureCommand>()); + this->AddCTestCommand("ctest_coverage", + cm::make_unique<cmCTestCoverageCommand>()); this->AddCTestCommand("ctest_empty_binary_directory", - new cmCTestEmptyBinaryDirectoryCommand); - this->AddCTestCommand("ctest_memcheck", new cmCTestMemCheckCommand); + cm::make_unique<cmCTestEmptyBinaryDirectoryCommand>()); + this->AddCTestCommand("ctest_memcheck", + cm::make_unique<cmCTestMemCheckCommand>()); this->AddCTestCommand("ctest_read_custom_files", - new cmCTestReadCustomFilesCommand); - this->AddCTestCommand("ctest_run_script", new cmCTestRunScriptCommand); - this->AddCTestCommand("ctest_sleep", new cmCTestSleepCommand); - this->AddCTestCommand("ctest_start", new cmCTestStartCommand); - this->AddCTestCommand("ctest_submit", new cmCTestSubmitCommand); - this->AddCTestCommand("ctest_test", new cmCTestTestCommand); - this->AddCTestCommand("ctest_update", new cmCTestUpdateCommand); - this->AddCTestCommand("ctest_upload", new cmCTestUploadCommand); + cm::make_unique<cmCTestReadCustomFilesCommand>()); + this->AddCTestCommand("ctest_run_script", + cm::make_unique<cmCTestRunScriptCommand>()); + this->AddCTestCommand("ctest_sleep", cm::make_unique<cmCTestSleepCommand>()); + this->AddCTestCommand("ctest_start", cm::make_unique<cmCTestStartCommand>()); + this->AddCTestCommand("ctest_submit", + cm::make_unique<cmCTestSubmitCommand>()); + this->AddCTestCommand("ctest_test", cm::make_unique<cmCTestTestCommand>()); + this->AddCTestCommand("ctest_update", + cm::make_unique<cmCTestUpdateCommand>()); + this->AddCTestCommand("ctest_upload", + cm::make_unique<cmCTestUploadCommand>()); } // this sets up some variables for the script to use, creates the required @@ -340,31 +328,29 @@ int cmCTestScriptHandler::ReadInScript(const std::string& total_script_arg) this->CreateCMake(); // set a variable with the path to the current script - this->Makefile->AddDefinition( - "CTEST_SCRIPT_DIRECTORY", cmSystemTools::GetFilenamePath(script).c_str()); - this->Makefile->AddDefinition( - "CTEST_SCRIPT_NAME", cmSystemTools::GetFilenameName(script).c_str()); + this->Makefile->AddDefinition("CTEST_SCRIPT_DIRECTORY", + cmSystemTools::GetFilenamePath(script)); + this->Makefile->AddDefinition("CTEST_SCRIPT_NAME", + cmSystemTools::GetFilenameName(script)); this->Makefile->AddDefinition("CTEST_EXECUTABLE_NAME", - cmSystemTools::GetCTestCommand().c_str()); + cmSystemTools::GetCTestCommand()); this->Makefile->AddDefinition("CMAKE_EXECUTABLE_NAME", - cmSystemTools::GetCMakeCommand().c_str()); - this->Makefile->AddDefinition("CTEST_RUN_CURRENT_SCRIPT", true); + cmSystemTools::GetCMakeCommand()); + this->Makefile->AddDefinitionBool("CTEST_RUN_CURRENT_SCRIPT", true); this->SetRunCurrentScript(true); this->UpdateElapsedTime(); // add the script arg if defined if (!script_arg.empty()) { - this->Makefile->AddDefinition("CTEST_SCRIPT_ARG", script_arg.c_str()); + this->Makefile->AddDefinition("CTEST_SCRIPT_ARG", script_arg); } #if defined(__CYGWIN__) this->Makefile->AddDefinition("CMAKE_LEGACY_CYGWIN_WIN32", "0"); #endif - // always add a function blocker to update the elapsed time - cmCTestScriptFunctionBlocker* f = new cmCTestScriptFunctionBlocker(); - f->CTestScriptHandler = this; - this->Makefile->AddFunctionBlocker(f); + // set a callback function to update the elapsed time + this->Makefile->OnExecuteCommand([this] { this->UpdateElapsedTime(); }); /* Execute CTestScriptMode.cmake, which loads CMakeDetermineSystem and CMakeSystemSpecificInformation, so @@ -384,7 +370,7 @@ int cmCTestScriptHandler::ReadInScript(const std::string& total_script_arg) const std::map<std::string, std::string>& defs = this->CTest->GetDefinitions(); for (auto const& d : defs) { - this->Makefile->AddDefinition(d.first, d.second.c_str()); + this->Makefile->AddDefinition(d.first, d.second); } // finally read in the script @@ -465,12 +451,13 @@ int cmCTestScriptHandler::ExtractVariables() // make sure the required info is here if (this->SourceDir.empty() || this->BinaryDir.empty() || this->CTestCmd.empty()) { - std::string msg = "CTEST_SOURCE_DIRECTORY = "; - msg += (!this->SourceDir.empty()) ? this->SourceDir.c_str() : "(Null)"; - msg += "\nCTEST_BINARY_DIRECTORY = "; - msg += (!this->BinaryDir.empty()) ? this->BinaryDir.c_str() : "(Null)"; - msg += "\nCTEST_COMMAND = "; - msg += (!this->CTestCmd.empty()) ? this->CTestCmd.c_str() : "(Null)"; + std::string msg = + cmStrCat("CTEST_SOURCE_DIRECTORY = ", + (!this->SourceDir.empty()) ? this->SourceDir.c_str() : "(Null)", + "\nCTEST_BINARY_DIRECTORY = ", + (!this->BinaryDir.empty()) ? this->BinaryDir.c_str() : "(Null)", + "\nCTEST_COMMAND = ", + (!this->CTestCmd.empty()) ? this->CTestCmd.c_str() : "(Null)"); cmSystemTools::Error( "Some required settings in the configuration file were missing:\n" + msg); @@ -509,7 +496,7 @@ void cmCTestScriptHandler::SleepInSeconds(unsigned int secondsToWait) int cmCTestScriptHandler::RunConfigurationScript( const std::string& total_script_arg, bool pscope) { -#ifdef CMAKE_BUILD_WITH_CMAKE +#ifndef CMAKE_BOOTSTRAP cmSystemTools::SaveRestoreEnvironment sre; #endif @@ -557,8 +544,7 @@ int cmCTestScriptHandler::RunCurrentScript() // set any environment variables if (!this->CTestEnv.empty()) { - std::vector<std::string> envArgs; - cmSystemTools::ExpandListArgument(this->CTestEnv, envArgs); + std::vector<std::string> envArgs = cmExpandedList(this->CTestEnv); cmSystemTools::AppendEnv(envArgs); } @@ -624,10 +610,8 @@ int cmCTestScriptHandler::BackupDirectories() int retVal; // compute the backup names - this->BackupSourceDir = this->SourceDir; - this->BackupSourceDir += "_CMakeBackup"; - this->BackupBinaryDir = this->BinaryDir; - this->BackupBinaryDir += "_CMakeBackup"; + this->BackupSourceDir = cmStrCat(this->SourceDir, "_CMakeBackup"); + this->BackupBinaryDir = cmStrCat(this->BinaryDir, "_CMakeBackup"); // backup the binary and src directories if requested if (this->Backup) { @@ -664,12 +648,9 @@ int cmCTestScriptHandler::PerformExtraUpdates() // do an initial cvs update as required command = this->UpdateCmd; for (std::string const& eu : this->ExtraUpdates) { - std::vector<std::string> cvsArgs; - cmSystemTools::ExpandListArgument(eu, cvsArgs); + std::vector<std::string> cvsArgs = cmExpandedList(eu); if (cvsArgs.size() == 2) { - std::string fullCommand = command; - fullCommand += " update "; - fullCommand += cvsArgs[1]; + std::string fullCommand = cmStrCat(command, " update ", cvsArgs[1]); output.clear(); retVal = 0; cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, @@ -678,8 +659,8 @@ int cmCTestScriptHandler::PerformExtraUpdates() fullCommand, &output, &output, &retVal, cvsArgs[0].c_str(), this->HandlerVerbose, cmDuration::zero() /*this->TimeOut*/); if (!res || retVal != 0) { - cmSystemTools::Error("Unable to perform extra updates:\n" + eu + - "\nWith output:\n" + output); + cmSystemTools::Error(cmStrCat("Unable to perform extra updates:\n", eu, + "\nWith output:\n", output)); return 0; } } @@ -770,9 +751,7 @@ int cmCTestScriptHandler::RunConfigurationDashboard() int cmakeFailed = 0; std::string cmakeFailedOuput; if (!this->CMakeCmd.empty()) { - command = this->CMakeCmd; - command += " \""; - command += this->SourceDir; + command = cmStrCat(this->CMakeCmd, " \"", this->SourceDir); output.clear(); command += "\""; retVal = 0; @@ -808,8 +787,7 @@ int cmCTestScriptHandler::RunConfigurationDashboard() } // run ctest, it may be more than one command in here - std::vector<std::string> ctestCommands; - cmSystemTools::ExpandListArgument(this->CTestCmd, ctestCommands); + std::vector<std::string> ctestCommands = cmExpandedList(this->CTestCmd); // for each variable/argument do a putenv for (std::string const& ctestCommand : ctestCommands) { command = ctestCommand; @@ -853,8 +831,7 @@ int cmCTestScriptHandler::RunConfigurationDashboard() bool cmCTestScriptHandler::WriteInitialCache(const char* directory, const char* text) { - std::string cacheFile = directory; - cacheFile += "/CMakeCache.txt"; + std::string cacheFile = cmStrCat(directory, "/CMakeCache.txt"); cmGeneratedFileStream fout(cacheFile); if (!fout) { return false; @@ -919,8 +896,7 @@ bool cmCTestScriptHandler::EmptyBinaryDirectory(const char* sname) } // try to avoid deleting directories that we shouldn't - std::string check = sname; - check += "/CMakeCache.txt"; + std::string check = cmStrCat(sname, "/CMakeCache.txt"); if (!cmSystemTools::FileExists(check)) { return false; @@ -949,7 +925,7 @@ bool cmCTestScriptHandler::TryToRemoveBinaryDirectoryOnce( continue; } - std::string fullPath = directoryPath + std::string("/") + path; + std::string fullPath = cmStrCat(directoryPath, "/", path); bool isDirectory = cmSystemTools::FileIsDirectory(fullPath) && !cmSystemTools::FileIsSymlink(fullPath); diff --git a/Source/CTest/cmCTestScriptHandler.h b/Source/CTest/cmCTestScriptHandler.h index d93b5f8..b2e8cbf 100644 --- a/Source/CTest/cmCTestScriptHandler.h +++ b/Source/CTest/cmCTestScriptHandler.h @@ -9,6 +9,7 @@ #include "cmDuration.h" #include <chrono> +#include <memory> #include <string> #include <vector> @@ -131,7 +132,8 @@ private: int RunConfigurationDashboard(); // Add ctest command - void AddCTestCommand(std::string const& name, cmCTestCommand* command); + void AddCTestCommand(std::string const& name, + std::unique_ptr<cmCTestCommand> command); // Try to remove the binary directory once static bool TryToRemoveBinaryDirectoryOnce(const std::string& directoryPath); diff --git a/Source/CTest/cmCTestSleepCommand.h b/Source/CTest/cmCTestSleepCommand.h index 5cd185a..7b17081 100644 --- a/Source/CTest/cmCTestSleepCommand.h +++ b/Source/CTest/cmCTestSleepCommand.h @@ -6,11 +6,14 @@ #include "cmConfigure.h" // IWYU pragma: keep #include "cmCTestCommand.h" +#include "cmCommand.h" #include <string> +#include <utility> #include <vector> -class cmCommand; +#include "cm_memory.hxx" + class cmExecutionStatus; /** \class cmCTestSleep @@ -27,12 +30,12 @@ public: /** * This is a virtual constructor for the command. */ - cmCommand* Clone() override + std::unique_ptr<cmCommand> Clone() override { - cmCTestSleepCommand* ni = new cmCTestSleepCommand; + auto ni = cm::make_unique<cmCTestSleepCommand>(); ni->CTest = this->CTest; ni->CTestScriptHandler = this->CTestScriptHandler; - return ni; + return std::unique_ptr<cmCommand>(std::move(ni)); } /** diff --git a/Source/CTest/cmCTestStartCommand.cxx b/Source/CTest/cmCTestStartCommand.cxx index 67ff2db..e4a1844 100644 --- a/Source/CTest/cmCTestStartCommand.cxx +++ b/Source/CTest/cmCTestStartCommand.cxx @@ -33,14 +33,16 @@ bool cmCTestStartCommand::InitialPass(std::vector<std::string> const& args, const char* bld_dir = nullptr; while (cnt < args.size()) { - if (args[cnt] == "TRACK") { + if (args[cnt] == "GROUP" || args[cnt] == "TRACK") { cnt++; if (cnt >= args.size() || args[cnt] == "APPEND" || args[cnt] == "QUIET") { - this->SetError("TRACK argument missing track name"); + std::ostringstream e; + e << args[cnt - 1] << " argument missing group name"; + this->SetError(e.str()); return false; } - this->CTest->SetSpecificTrack(args[cnt].c_str()); + this->CTest->SetSpecificGroup(args[cnt].c_str()); cnt++; } else if (args[cnt] == "APPEND") { cnt++; @@ -113,10 +115,10 @@ bool cmCTestStartCommand::InitialPass(std::vector<std::string> const& args, << " Build directory: " << bld_dir << std::endl, this->Quiet); } - const char* track = this->CTest->GetSpecificTrack(); - if (track) { + const char* group = this->CTest->GetSpecificGroup(); + if (group) { cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, - " Track: " << track << std::endl, this->Quiet); + " Group: " << group << std::endl, this->Quiet); } // Log startup actions. diff --git a/Source/CTest/cmCTestStartCommand.h b/Source/CTest/cmCTestStartCommand.h index 542f27c..7c71f36 100644 --- a/Source/CTest/cmCTestStartCommand.h +++ b/Source/CTest/cmCTestStartCommand.h @@ -6,12 +6,15 @@ #include "cmConfigure.h" // IWYU pragma: keep #include "cmCTestCommand.h" +#include "cmCommand.h" #include <iosfwd> #include <string> +#include <utility> #include <vector> -class cmCommand; +#include "cm_memory.hxx" + class cmExecutionStatus; /** \class cmCTestStart @@ -27,14 +30,14 @@ public: /** * This is a virtual constructor for the command. */ - cmCommand* Clone() override + std::unique_ptr<cmCommand> Clone() override { - cmCTestStartCommand* ni = new cmCTestStartCommand; + auto ni = cm::make_unique<cmCTestStartCommand>(); ni->CTest = this->CTest; ni->CTestScriptHandler = this->CTestScriptHandler; ni->CreateNewTag = this->CreateNewTag; ni->Quiet = this->Quiet; - return ni; + return std::unique_ptr<cmCommand>(std::move(ni)); } /** diff --git a/Source/CTest/cmCTestSubmitCommand.cxx b/Source/CTest/cmCTestSubmitCommand.cxx index afc3e67..d16aac0 100644 --- a/Source/CTest/cmCTestSubmitCommand.cxx +++ b/Source/CTest/cmCTestSubmitCommand.cxx @@ -4,11 +4,16 @@ #include "cmCTest.h" #include "cmCTestSubmitHandler.h" +#include "cmCommand.h" #include "cmMakefile.h" #include "cmMessageType.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include <sstream> +#include <utility> + +#include "cm_memory.hxx" class cmExecutionStatus; @@ -27,12 +32,12 @@ cmCTestSubmitCommand::cmCTestSubmitCommand() /** * This is a virtual constructor for the command. */ -cmCommand* cmCTestSubmitCommand::Clone() +std::unique_ptr<cmCommand> cmCTestSubmitCommand::Clone() { - cmCTestSubmitCommand* ni = new cmCTestSubmitCommand; + auto ni = cm::make_unique<cmCTestSubmitCommand>(); ni->CTest = this->CTest; ni->CTestScriptHandler = this->CTestScriptHandler; - return ni; + return std::unique_ptr<cmCommand>(std::move(ni)); } cmCTestGenericHandler* cmCTestSubmitCommand::InitializeHandler() @@ -63,16 +68,14 @@ cmCTestGenericHandler* cmCTestSubmitCommand::InitializeHandler() const char* notesFilesVariable = this->Makefile->GetDefinition("CTEST_NOTES_FILES"); if (notesFilesVariable) { - std::vector<std::string> notesFiles; - cmSystemTools::ExpandListArgument(notesFilesVariable, notesFiles); + std::vector<std::string> notesFiles = cmExpandedList(notesFilesVariable); this->CTest->GenerateNotesFile(notesFiles); } const char* extraFilesVariable = this->Makefile->GetDefinition("CTEST_EXTRA_SUBMIT_FILES"); if (extraFilesVariable) { - std::vector<std::string> extraFiles; - cmSystemTools::ExpandListArgument(extraFilesVariable, extraFiles); + std::vector<std::string> extraFiles = cmExpandedList(extraFilesVariable); if (!this->CTest->SubmitExtraFiles(extraFiles)) { this->SetError("problem submitting extra files."); return nullptr; @@ -139,7 +142,7 @@ bool cmCTestSubmitCommand::InitialPass(std::vector<std::string> const& args, if (this->Values[cts_BUILD_ID] && *this->Values[cts_BUILD_ID]) { this->Makefile->AddDefinition(this->Values[cts_BUILD_ID], - this->CTest->GetBuildID().c_str()); + this->CTest->GetBuildID()); } return ret; diff --git a/Source/CTest/cmCTestSubmitCommand.h b/Source/CTest/cmCTestSubmitCommand.h index 1e27046..5bbcd39 100644 --- a/Source/CTest/cmCTestSubmitCommand.h +++ b/Source/CTest/cmCTestSubmitCommand.h @@ -8,12 +8,13 @@ #include "cmCTest.h" #include "cmCTestHandlerCommand.h" +#include <memory> #include <set> #include <string> #include <vector> -class cmCTestGenericHandler; class cmCommand; +class cmCTestGenericHandler; class cmExecutionStatus; /** \class cmCTestSubmit @@ -26,7 +27,7 @@ class cmCTestSubmitCommand : public cmCTestHandlerCommand { public: cmCTestSubmitCommand(); - cmCommand* Clone() override; + std::unique_ptr<cmCommand> Clone() override; bool InitialPass(std::vector<std::string> const& args, cmExecutionStatus& status) override; diff --git a/Source/CTest/cmCTestSubmitHandler.cxx b/Source/CTest/cmCTestSubmitHandler.cxx index 54c4bae..a178b44 100644 --- a/Source/CTest/cmCTestSubmitHandler.cxx +++ b/Source/CTest/cmCTestSubmitHandler.cxx @@ -19,6 +19,7 @@ #include "cmDuration.h" #include "cmGeneratedFileStream.h" #include "cmState.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmXMLParser.h" #include "cmake.h" @@ -154,8 +155,7 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP( /* In windows, this will init the winsock stuff */ ::curl_global_init(CURL_GLOBAL_ALL); std::string curlopt(this->CTest->GetCTestConfiguration("CurlOptions")); - std::vector<std::string> args; - cmSystemTools::ExpandListArgument(curlopt, args); + std::vector<std::string> args = cmExpandedList(curlopt); bool verifyPeerOff = false; bool verifyHostOff = false; for (std::string const& arg : args) { @@ -224,7 +224,7 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP( std::string local_file = file; bool initialize_cdash_buildid = false; if (!cmSystemTools::FileExists(local_file)) { - local_file = localprefix + "/" + file; + local_file = cmStrCat(localprefix, "/", file); // If this file exists within the local Testing directory we assume // that it will be associated with the current build in CDash. initialize_cdash_buildid = true; @@ -236,9 +236,9 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP( << remote_file << std::endl; std::string ofile = cmSystemTools::EncodeURL(remote_file); - std::string upload_as = url + - ((url.find('?') == std::string::npos) ? '?' : '&') + - "FileName=" + ofile; + std::string upload_as = + cmStrCat(url, ((url.find('?') == std::string::npos) ? '?' : '&'), + "FileName=", ofile); if (initialize_cdash_buildid) { // Provide extra arguments to CDash so that it can initialize and @@ -279,7 +279,7 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP( upload_as += "&MD5="; - if (cmSystemTools::IsOn(this->GetOption("InternalTest"))) { + if (cmIsOn(this->GetOption("InternalTest"))) { upload_as += "bad_md5sum"; } else { upload_as += @@ -498,8 +498,7 @@ int cmCTestSubmitHandler::HandleCDashUploadFile(std::string const& file, cmCTestCurl curl(this->CTest); curl.SetQuiet(this->Quiet); std::string curlopt(this->CTest->GetCTestConfiguration("CurlOptions")); - std::vector<std::string> args; - cmSystemTools::ExpandListArgument(curlopt, args); + std::vector<std::string> args = cmExpandedList(curlopt); curl.SetCurlOptions(args); curl.SetTimeOutSeconds(SUBMIT_TIMEOUT_IN_SECONDS_DEFAULT); curl.SetHttpHeaders(this->HttpHeaders); @@ -516,7 +515,7 @@ int cmCTestSubmitHandler::HandleCDashUploadFile(std::string const& file, "Only http and https are supported for CDASH_UPLOAD\n"); return -1; } - bool internalTest = cmSystemTools::IsOn(this->GetOption("InternalTest")); + bool internalTest = cmIsOn(this->GetOption("InternalTest")); // Get RETRY_COUNT and RETRY_DELAY values if they were set. std::string retryDelayString = this->GetOption("RetryDelay") == nullptr @@ -528,8 +527,7 @@ int cmCTestSubmitHandler::HandleCDashUploadFile(std::string const& file, auto retryDelay = std::chrono::seconds(0); if (!retryDelayString.empty()) { unsigned long retryDelayValue = 0; - if (!cmSystemTools::StringToULong(retryDelayString.c_str(), - &retryDelayValue)) { + if (!cmStrToULong(retryDelayString, &retryDelayValue)) { cmCTestLog(this->CTest, WARNING, "Invalid value for 'RETRY_DELAY' : " << retryDelayString << std::endl); @@ -539,7 +537,7 @@ int cmCTestSubmitHandler::HandleCDashUploadFile(std::string const& file, } unsigned long retryCount = 0; if (!retryCountString.empty()) { - if (!cmSystemTools::StringToULong(retryCountString.c_str(), &retryCount)) { + if (!cmStrToULong(retryCountString, &retryCount)) { cmCTestLog(this->CTest, WARNING, "Invalid value for 'RETRY_DELAY' : " << retryCountString << std::endl); @@ -569,6 +567,11 @@ int cmCTestSubmitHandler::HandleCDashUploadFile(std::string const& file, << curl.Escape(this->CTest->GetCTestConfiguration("BuildName")) << "&" << "site=" << curl.Escape(this->CTest->GetCTestConfiguration("Site")) << "&" + << "group=" << curl.Escape(this->CTest->GetTestModelString()) + << "&" + // For now, we send both "track" and "group" to CDash in case we're + // submitting to an older instance that still expects the prior + // terminology. << "track=" << curl.Escape(this->CTest->GetTestModelString()) << "&" << "starttime=" << timeNow << "&" << "endtime=" << timeNow << "&" @@ -837,10 +840,10 @@ int cmCTestSubmitHandler::ProcessHandler() } cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, "Submit files\n", this->Quiet); - const char* specificTrack = this->CTest->GetSpecificTrack(); - if (specificTrack) { + const char* specificGroup = this->CTest->GetSpecificGroup(); + if (specificGroup) { cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, - " Send to track: " << specificTrack << std::endl, + " Send to group: " << specificGroup << std::endl, this->Quiet); } this->SetLogFile(&ofs); diff --git a/Source/CTest/cmCTestTestCommand.cxx b/Source/CTest/cmCTestTestCommand.cxx index cfd5e3d..24de5b4 100644 --- a/Source/CTest/cmCTestTestCommand.cxx +++ b/Source/CTest/cmCTestTestCommand.cxx @@ -7,7 +7,7 @@ #include "cmCTestTestHandler.h" #include "cmDuration.h" #include "cmMakefile.h" -#include "cmSystemTools.h" +#include "cmStringAlgorithms.h" #include <chrono> #include <sstream> @@ -110,15 +110,14 @@ cmCTestGenericHandler* cmCTestTestCommand::InitializeHandler() unsigned long testLoad; const char* ctestTestLoad = this->Makefile->GetDefinition("CTEST_TEST_LOAD"); if (this->Values[ctt_TEST_LOAD] && *this->Values[ctt_TEST_LOAD]) { - if (!cmSystemTools::StringToULong(this->Values[ctt_TEST_LOAD], - &testLoad)) { + if (!cmStrToULong(this->Values[ctt_TEST_LOAD], &testLoad)) { testLoad = 0; cmCTestLog(this->CTest, WARNING, "Invalid value for 'TEST_LOAD' : " << this->Values[ctt_TEST_LOAD] << std::endl); } } else if (ctestTestLoad && *ctestTestLoad) { - if (!cmSystemTools::StringToULong(ctestTestLoad, &testLoad)) { + if (!cmStrToULong(ctestTestLoad, &testLoad)) { testLoad = 0; cmCTestLog(this->CTest, WARNING, "Invalid value for 'CTEST_TEST_LOAD' : " << ctestTestLoad diff --git a/Source/CTest/cmCTestTestCommand.h b/Source/CTest/cmCTestTestCommand.h index 11c0db9..d74136c 100644 --- a/Source/CTest/cmCTestTestCommand.h +++ b/Source/CTest/cmCTestTestCommand.h @@ -6,11 +6,14 @@ #include "cmConfigure.h" // IWYU pragma: keep #include "cmCTestHandlerCommand.h" +#include "cmCommand.h" #include <string> +#include <utility> + +#include "cm_memory.hxx" class cmCTestGenericHandler; -class cmCommand; /** \class cmCTestTest * \brief Run a ctest script @@ -25,12 +28,12 @@ public: /** * This is a virtual constructor for the command. */ - cmCommand* Clone() override + std::unique_ptr<cmCommand> Clone() override { - cmCTestTestCommand* ni = new cmCTestTestCommand; + auto ni = cm::make_unique<cmCTestTestCommand>(); ni->CTest = this->CTest; ni->CTestScriptHandler = this->CTestScriptHandler; - return ni; + return std::unique_ptr<cmCommand>(std::move(ni)); } /** diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx index 0ed56c8..9181daa 100644 --- a/Source/CTest/cmCTestTestHandler.cxx +++ b/Source/CTest/cmCTestTestHandler.cxx @@ -11,12 +11,14 @@ #include <functional> #include <iomanip> #include <iterator> -#include <memory> // IWYU pragma: keep #include <set> #include <sstream> #include <stdio.h> #include <stdlib.h> #include <time.h> +#include <utility> + +#include "cm_memory.hxx" #include "cmAlgorithms.h" #include "cmCTest.h" @@ -28,6 +30,7 @@ #include "cmMakefile.h" #include "cmState.h" #include "cmStateSnapshot.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmWorkingDirectory.h" #include "cmXMLWriter.h" @@ -43,11 +46,11 @@ public: /** * This is a virtual constructor for the command. */ - cmCommand* Clone() override + std::unique_ptr<cmCommand> Clone() override { - cmCTestSubdirCommand* c = new cmCTestSubdirCommand; + auto c = cm::make_unique<cmCTestSubdirCommand>(); c->TestHandler = this->TestHandler; - return c; + return std::unique_ptr<cmCommand>(std::move(c)); } /** @@ -74,9 +77,7 @@ bool cmCTestSubdirCommand::InitialPass(std::vector<std::string> const& args, if (cmSystemTools::FileIsFullPath(arg)) { fname = arg; } else { - fname = cwd; - fname += "/"; - fname += arg; + fname = cmStrCat(cwd, '/', arg); } if (!cmSystemTools::FileIsDirectory(fname)) { @@ -107,8 +108,7 @@ bool cmCTestSubdirCommand::InitialPass(std::vector<std::string> const& args, readit = this->Makefile->ReadDependentFile(fname); } if (!readit) { - std::string m = "Could not find include file: "; - m += fname; + std::string m = cmStrCat("Could not find include file: ", fname); this->SetError(m); return false; } @@ -122,11 +122,11 @@ public: /** * This is a virtual constructor for the command. */ - cmCommand* Clone() override + std::unique_ptr<cmCommand> Clone() override { - cmCTestAddSubdirectoryCommand* c = new cmCTestAddSubdirectoryCommand; + auto c = cm::make_unique<cmCTestAddSubdirectoryCommand>(); c->TestHandler = this->TestHandler; - return c; + return std::unique_ptr<cmCommand>(std::move(c)); } /** @@ -147,9 +147,8 @@ bool cmCTestAddSubdirectoryCommand::InitialPass( return false; } - std::string fname = cmSystemTools::GetCurrentWorkingDirectory(); - fname += "/"; - fname += args[0]; + std::string fname = + cmStrCat(cmSystemTools::GetCurrentWorkingDirectory(), '/', args[0]); if (!cmSystemTools::FileExists(fname)) { // No subdirectory? So what... @@ -173,8 +172,7 @@ bool cmCTestAddSubdirectoryCommand::InitialPass( readit = this->Makefile->ReadDependentFile(fname); } if (!readit) { - std::string m = "Could not find include file: "; - m += fname; + std::string m = cmStrCat("Could not find include file: ", fname); this->SetError(m); return false; } @@ -187,11 +185,11 @@ public: /** * This is a virtual constructor for the command. */ - cmCommand* Clone() override + std::unique_ptr<cmCommand> Clone() override { - cmCTestAddTestCommand* c = new cmCTestAddTestCommand; + auto c = cm::make_unique<cmCTestAddTestCommand>(); c->TestHandler = this->TestHandler; - return c; + return std::unique_ptr<cmCommand>(std::move(c)); } /** @@ -220,11 +218,11 @@ public: /** * This is a virtual constructor for the command. */ - cmCommand* Clone() override + std::unique_ptr<cmCommand> Clone() override { - cmCTestSetTestsPropertiesCommand* c = new cmCTestSetTestsPropertiesCommand; + auto c = cm::make_unique<cmCTestSetTestsPropertiesCommand>(); c->TestHandler = this->TestHandler; - return c; + return std::unique_ptr<cmCommand>(std::move(c)); } /** @@ -249,12 +247,11 @@ public: /** * This is a virtual constructor for the command. */ - cmCommand* Clone() override + std::unique_ptr<cmCommand> Clone() override { - cmCTestSetDirectoryPropertiesCommand* c = - new cmCTestSetDirectoryPropertiesCommand; + auto c = cm::make_unique<cmCTestSetDirectoryPropertiesCommand>(); c->TestHandler = this->TestHandler; - return c; + return std::unique_ptr<cmCommand>(std::move(c)); } /** @@ -422,54 +419,11 @@ int cmCTestTestHandler::PostProcessHandler() return 1; } -// clearly it would be nice if this were broken up into a few smaller -// functions and commented... int cmCTestTestHandler::ProcessHandler() { - // Update internal data structure from generic one - this->SetTestsToRunInformation(this->GetOption("TestsToRunInformation")); - this->SetUseUnion(cmSystemTools::IsOn(this->GetOption("UseUnion"))); - if (cmSystemTools::IsOn(this->GetOption("ScheduleRandom"))) { - this->CTest->SetScheduleType("Random"); - } - if (this->GetOption("ParallelLevel")) { - this->CTest->SetParallelLevel(atoi(this->GetOption("ParallelLevel"))); - } - - const char* val; - val = this->GetOption("LabelRegularExpression"); - if (val) { - this->UseIncludeLabelRegExpFlag = true; - this->IncludeLabelRegExp = val; - } - val = this->GetOption("ExcludeLabelRegularExpression"); - if (val) { - this->UseExcludeLabelRegExpFlag = true; - this->ExcludeLabelRegExp = val; - } - val = this->GetOption("IncludeRegularExpression"); - if (val) { - this->UseIncludeRegExp(); - this->SetIncludeRegExp(val); - } - val = this->GetOption("ExcludeRegularExpression"); - if (val) { - this->UseExcludeRegExp(); - this->SetExcludeRegExp(val); - } - val = this->GetOption("ExcludeFixtureRegularExpression"); - if (val) { - this->ExcludeFixtureRegExp = val; - } - val = this->GetOption("ExcludeFixtureSetupRegularExpression"); - if (val) { - this->ExcludeFixtureSetupRegExp = val; - } - val = this->GetOption("ExcludeFixtureCleanupRegularExpression"); - if (val) { - this->ExcludeFixtureCleanupRegExp = val; + if (!this->ProcessOptions()) { + return -1; } - this->SetRerunFailed(cmSystemTools::IsOn(this->GetOption("RerunFailed"))); this->TestResults.clear(); @@ -489,7 +443,6 @@ int cmCTestTestHandler::ProcessHandler() std::vector<std::string> passed; std::vector<std::string> failed; - int total; // start the real time clock auto clock_start = std::chrono::steady_clock::now(); @@ -498,9 +451,7 @@ int cmCTestTestHandler::ProcessHandler() auto clock_finish = std::chrono::steady_clock::now(); - total = int(passed.size()) + int(failed.size()); - - if (total == 0) { + if (passed.size() + failed.size() == 0) { if (!this->CTest->GetShowOnly() && !this->CTest->ShouldPrintLabels()) { cmCTestLog(this->CTest, ERROR_MESSAGE, "No tests were found!!!" << std::endl); @@ -518,105 +469,192 @@ int cmCTestTestHandler::ProcessHandler() } } - typedef std::set<cmCTestTestHandler::cmCTestTestResult, - cmCTestTestResultLess> - SetOfTests; SetOfTests resultsSet(this->TestResults.begin(), this->TestResults.end()); std::vector<cmCTestTestHandler::cmCTestTestResult> disabledTests; for (cmCTestTestResult const& ft : resultsSet) { - if (cmHasLiteralPrefix(ft.CompletionStatus, "SKIP_RETURN_CODE=") || + if (cmHasLiteralPrefix(ft.CompletionStatus, "SKIP_") || ft.CompletionStatus == "Disabled") { disabledTests.push_back(ft); } } - float percent = float(passed.size()) * 100.0f / float(total); - if (!failed.empty() && percent > 99) { - percent = 99; - } + cmDuration durationInSecs = clock_finish - clock_start; + this->LogTestSummary(passed, failed, durationInSecs); - std::string passColorCode; - std::string failedColorCode; - if (failed.empty()) { - passColorCode = this->CTest->GetColorCode(cmCTest::Color::GREEN); - } else { - failedColorCode = this->CTest->GetColorCode(cmCTest::Color::RED); - } + this->LogDisabledTests(disabledTests); + + this->LogFailedTests(failed, resultsSet); + } + + if (!this->GenerateXML()) { + return 1; + } + + if (!this->PostProcessHandler()) { + this->LogFile = nullptr; + return -1; + } + + if (!failed.empty()) { + this->LogFile = nullptr; + return -1; + } + this->LogFile = nullptr; + return 0; +} + +bool cmCTestTestHandler::ProcessOptions() +{ + // Update internal data structure from generic one + this->SetTestsToRunInformation(this->GetOption("TestsToRunInformation")); + this->SetUseUnion(cmIsOn(this->GetOption("UseUnion"))); + if (cmIsOn(this->GetOption("ScheduleRandom"))) { + this->CTest->SetScheduleType("Random"); + } + if (this->GetOption("ParallelLevel")) { + this->CTest->SetParallelLevel(atoi(this->GetOption("ParallelLevel"))); + } + + const char* val; + val = this->GetOption("LabelRegularExpression"); + if (val) { + this->UseIncludeLabelRegExpFlag = true; + this->IncludeLabelRegExp = val; + } + val = this->GetOption("ExcludeLabelRegularExpression"); + if (val) { + this->UseExcludeLabelRegExpFlag = true; + this->ExcludeLabelRegExp = val; + } + val = this->GetOption("IncludeRegularExpression"); + if (val) { + this->UseIncludeRegExp(); + this->SetIncludeRegExp(val); + } + val = this->GetOption("ExcludeRegularExpression"); + if (val) { + this->UseExcludeRegExp(); + this->SetExcludeRegExp(val); + } + val = this->GetOption("ExcludeFixtureRegularExpression"); + if (val) { + this->ExcludeFixtureRegExp = val; + } + val = this->GetOption("ExcludeFixtureSetupRegularExpression"); + if (val) { + this->ExcludeFixtureSetupRegExp = val; + } + val = this->GetOption("ExcludeFixtureCleanupRegularExpression"); + if (val) { + this->ExcludeFixtureCleanupRegExp = val; + } + this->SetRerunFailed(cmIsOn(this->GetOption("RerunFailed"))); + + return true; +} + +void cmCTestTestHandler::LogTestSummary(const std::vector<std::string>& passed, + const std::vector<std::string>& failed, + const cmDuration& durationInSecs) +{ + std::size_t total = passed.size() + failed.size(); + + float percent = float(passed.size()) * 100.0f / float(total); + if (!failed.empty() && percent > 99) { + percent = 99; + } + + std::string passColorCode; + std::string failedColorCode; + if (failed.empty()) { + passColorCode = this->CTest->GetColorCode(cmCTest::Color::GREEN); + } else { + failedColorCode = this->CTest->GetColorCode(cmCTest::Color::RED); + } + cmCTestLog(this->CTest, HANDLER_OUTPUT, + std::endl + << passColorCode << std::lround(percent) << "% tests passed" + << this->CTest->GetColorCode(cmCTest::Color::CLEAR_COLOR) + << ", " << failedColorCode << failed.size() << " tests failed" + << this->CTest->GetColorCode(cmCTest::Color::CLEAR_COLOR) + << " out of " << total << std::endl); + if ((!this->CTest->GetLabelsForSubprojects().empty() && + this->CTest->GetSubprojectSummary())) { + this->PrintLabelOrSubprojectSummary(true); + } + if (this->CTest->GetLabelSummary()) { + this->PrintLabelOrSubprojectSummary(false); + } + char realBuf[1024]; + sprintf(realBuf, "%6.2f sec", durationInSecs.count()); + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, + "\nTotal Test time (real) = " << realBuf << "\n", + this->Quiet); +} + +void cmCTestTestHandler::LogDisabledTests( + const std::vector<cmCTestTestResult>& disabledTests) +{ + if (!disabledTests.empty()) { + cmGeneratedFileStream ofs; cmCTestLog(this->CTest, HANDLER_OUTPUT, std::endl - << passColorCode << std::lround(percent) << "% tests passed" - << this->CTest->GetColorCode(cmCTest::Color::CLEAR_COLOR) - << ", " << failedColorCode << failed.size() << " tests failed" - << this->CTest->GetColorCode(cmCTest::Color::CLEAR_COLOR) - << " out of " << total << std::endl); - if ((!this->CTest->GetLabelsForSubprojects().empty() && - this->CTest->GetSubprojectSummary())) { - this->PrintLabelOrSubprojectSummary(true); - } - if (this->CTest->GetLabelSummary()) { - this->PrintLabelOrSubprojectSummary(false); - } - char realBuf[1024]; - cmDuration durationInSecs = clock_finish - clock_start; - sprintf(realBuf, "%6.2f sec", durationInSecs.count()); - cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, - "\nTotal Test time (real) = " << realBuf << "\n", - this->Quiet); - - if (!disabledTests.empty()) { - cmGeneratedFileStream ofs; - cmCTestLog(this->CTest, HANDLER_OUTPUT, - std::endl - << "The following tests did not run:" << std::endl); - this->StartLogFile("TestsDisabled", ofs); + << "The following tests did not run:" << std::endl); + this->StartLogFile("TestsDisabled", ofs); - const char* disabled_reason; - cmCTestLog(this->CTest, HANDLER_OUTPUT, - this->CTest->GetColorCode(cmCTest::Color::BLUE)); - for (cmCTestTestResult const& dt : disabledTests) { - ofs << dt.TestCount << ":" << dt.Name << std::endl; - if (dt.CompletionStatus == "Disabled") { - disabled_reason = "Disabled"; - } else { - disabled_reason = "Skipped"; - } - cmCTestLog(this->CTest, HANDLER_OUTPUT, - "\t" << std::setw(3) << dt.TestCount << " - " << dt.Name - << " (" << disabled_reason << ")" << std::endl); + const char* disabled_reason; + cmCTestLog(this->CTest, HANDLER_OUTPUT, + this->CTest->GetColorCode(cmCTest::Color::BLUE)); + for (cmCTestTestResult const& dt : disabledTests) { + ofs << dt.TestCount << ":" << dt.Name << std::endl; + if (dt.CompletionStatus == "Disabled") { + disabled_reason = "Disabled"; + } else { + disabled_reason = "Skipped"; } cmCTestLog(this->CTest, HANDLER_OUTPUT, - this->CTest->GetColorCode(cmCTest::Color::CLEAR_COLOR)); + "\t" << std::setw(3) << dt.TestCount << " - " << dt.Name + << " (" << disabled_reason << ")" << std::endl); } + cmCTestLog(this->CTest, HANDLER_OUTPUT, + this->CTest->GetColorCode(cmCTest::Color::CLEAR_COLOR)); + } +} - if (!failed.empty()) { - cmGeneratedFileStream ofs; - cmCTestLog(this->CTest, HANDLER_OUTPUT, - std::endl - << "The following tests FAILED:" << std::endl); - this->StartLogFile("TestsFailed", ofs); - - for (cmCTestTestResult const& ft : resultsSet) { - if (ft.Status != cmCTestTestHandler::COMPLETED && - !cmHasLiteralPrefix(ft.CompletionStatus, "SKIP_RETURN_CODE=") && - ft.CompletionStatus != "Disabled") { - ofs << ft.TestCount << ":" << ft.Name << std::endl; - auto testColor = cmCTest::Color::RED; - if (this->GetTestStatus(ft) == "Not Run") { - testColor = cmCTest::Color::YELLOW; - } - cmCTestLog( - this->CTest, HANDLER_OUTPUT, - "\t" << this->CTest->GetColorCode(testColor) << std::setw(3) - << ft.TestCount << " - " << ft.Name << " (" - << this->GetTestStatus(ft) << ")" - << this->CTest->GetColorCode(cmCTest::Color::CLEAR_COLOR) - << std::endl); +void cmCTestTestHandler::LogFailedTests(const std::vector<std::string>& failed, + const SetOfTests& resultsSet) +{ + if (!failed.empty()) { + cmGeneratedFileStream ofs; + cmCTestLog(this->CTest, HANDLER_OUTPUT, + std::endl + << "The following tests FAILED:" << std::endl); + this->StartLogFile("TestsFailed", ofs); + + for (cmCTestTestResult const& ft : resultsSet) { + if (ft.Status != cmCTestTestHandler::COMPLETED && + !cmHasLiteralPrefix(ft.CompletionStatus, "SKIP_") && + ft.CompletionStatus != "Disabled") { + ofs << ft.TestCount << ":" << ft.Name << std::endl; + auto testColor = cmCTest::Color::RED; + if (this->GetTestStatus(ft) == "Not Run") { + testColor = cmCTest::Color::YELLOW; } + cmCTestLog( + this->CTest, HANDLER_OUTPUT, + "\t" << this->CTest->GetColorCode(testColor) << std::setw(3) + << ft.TestCount << " - " << ft.Name << " (" + << this->GetTestStatus(ft) << ")" + << this->CTest->GetColorCode(cmCTest::Color::CLEAR_COLOR) + << std::endl); } } } +} +bool cmCTestTestHandler::GenerateXML() +{ if (this->CTest->GetProduceXML()) { cmGeneratedFileStream xmlfile; if (!this->StartResultingXML( @@ -627,23 +665,13 @@ int cmCTestTestHandler::ProcessHandler() << (this->MemCheck ? "memory check" : "testing") << " XML file" << std::endl); this->LogFile = nullptr; - return 1; + return false; } cmXMLWriter xml(xmlfile); this->GenerateDartOutput(xml); } - if (!this->PostProcessHandler()) { - this->LogFile = nullptr; - return -1; - } - - if (!failed.empty()) { - this->LogFile = nullptr; - return -1; - } - this->LogFile = nullptr; - return 0; + return true; } void cmCTestTestHandler::PrintLabelOrSubprojectSummary(bool doSubProject) @@ -667,8 +695,7 @@ void cmCTestTestHandler::PrintLabelOrSubprojectSummary(bool doSubProject) } // if we are doing sub projects and this label is one, then use it // if we are not doing sub projects and the label is not one use it - if ((doSubProject && isSubprojectLabel) || - (!doSubProject && !isSubprojectLabel)) { + if (doSubProject == isSubprojectLabel) { if (l.size() > maxlen) { maxlen = l.size(); } @@ -683,7 +710,7 @@ void cmCTestTestHandler::PrintLabelOrSubprojectSummary(bool doSubProject) cmCTestTestProperties& p = *result.Properties; for (std::string const& l : p.Labels) { // only use labels found in labels - if (labels.find(l) != labels.end()) { + if (cmContains(labels, l)) { labelTimes[l] += result.ExecutionTime.count() * result.Properties->Processors; ++labelCounts[l]; @@ -825,17 +852,14 @@ void cmCTestTestHandler::ComputeTestList() if (this->UseUnion) { // if it is not in the list and not in the regexp then skip - if ((!this->TestsToRun.empty() && - std::find(this->TestsToRun.begin(), this->TestsToRun.end(), cnt) == - this->TestsToRun.end()) && + if ((!this->TestsToRun.empty() && !cmContains(this->TestsToRun, cnt)) && !tp.IsInBasedOnREOptions) { continue; } } else { // is this test in the list of tests to run? If not then skip it if ((!this->TestsToRun.empty() && - std::find(this->TestsToRun.begin(), this->TestsToRun.end(), - inREcnt) == this->TestsToRun.end()) || + !cmContains(this->TestsToRun, inREcnt)) || !tp.IsInBasedOnREOptions) { continue; } @@ -864,9 +888,7 @@ void cmCTestTestHandler::ComputeTestListForRerunFailed() cnt++; // if this test is not in our list of tests to run, then skip it. - if ((!this->TestsToRun.empty() && - std::find(this->TestsToRun.begin(), this->TestsToRun.end(), cnt) == - this->TestsToRun.end())) { + if (!this->TestsToRun.empty() && !cmContains(this->TestsToRun, cnt)) { continue; } @@ -987,8 +1009,7 @@ void cmCTestTestHandler::UpdateForFixtures(ListOfTests& tests) const sIt != setupRange.second; ++sIt) { const std::string& setupTestName = sIt->second->Name; tests[i].RequireSuccessDepends.insert(setupTestName); - if (std::find(tests[i].Depends.begin(), tests[i].Depends.end(), - setupTestName) == tests[i].Depends.end()) { + if (!cmContains(tests[i].Depends, setupTestName)) { tests[i].Depends.push_back(setupTestName); } } @@ -1095,8 +1116,7 @@ void cmCTestTestHandler::UpdateForFixtures(ListOfTests& tests) const const std::vector<size_t>& indices = cIt->second; for (size_t index : indices) { const std::string& reqTestName = tests[index].Name; - if (std::find(p.Depends.begin(), p.Depends.end(), reqTestName) == - p.Depends.end()) { + if (!cmContains(p.Depends, reqTestName)) { p.Depends.push_back(reqTestName); } } @@ -1109,8 +1129,7 @@ void cmCTestTestHandler::UpdateForFixtures(ListOfTests& tests) const const std::vector<size_t>& indices = cIt->second; for (size_t index : indices) { const std::string& setupTestName = tests[index].Name; - if (std::find(p.Depends.begin(), p.Depends.end(), setupTestName) == - p.Depends.end()) { + if (!cmContains(p.Depends, setupTestName)) { p.Depends.push_back(setupTestName); } } @@ -1527,50 +1546,32 @@ void cmCTestTestHandler::AddConfigurations( attemptedConfigs.emplace_back(); if (!ctest->GetConfigType().empty()) { - tempPath = filepath; - tempPath += ctest->GetConfigType(); - tempPath += "/"; - tempPath += filename; + tempPath = cmStrCat(filepath, ctest->GetConfigType(), '/', filename); attempted.push_back(tempPath); attemptedConfigs.push_back(ctest->GetConfigType()); // If the file is an OSX bundle then the configtype // will be at the start of the path - tempPath = ctest->GetConfigType(); - tempPath += "/"; - tempPath += filepath; - tempPath += filename; + tempPath = cmStrCat(ctest->GetConfigType(), '/', filepath, filename); attempted.push_back(tempPath); attemptedConfigs.push_back(ctest->GetConfigType()); } else { // no config specified - try some options... - tempPath = filepath; - tempPath += "Release/"; - tempPath += filename; + tempPath = cmStrCat(filepath, "Release/", filename); attempted.push_back(tempPath); attemptedConfigs.emplace_back("Release"); - tempPath = filepath; - tempPath += "Debug/"; - tempPath += filename; + tempPath = cmStrCat(filepath, "Debug/", filename); attempted.push_back(tempPath); attemptedConfigs.emplace_back("Debug"); - tempPath = filepath; - tempPath += "MinSizeRel/"; - tempPath += filename; + tempPath = cmStrCat(filepath, "MinSizeRel/", filename); attempted.push_back(tempPath); attemptedConfigs.emplace_back("MinSizeRel"); - tempPath = filepath; - tempPath += "RelWithDebInfo/"; - tempPath += filename; + tempPath = cmStrCat(filepath, "RelWithDebInfo/", filename); attempted.push_back(tempPath); attemptedConfigs.emplace_back("RelWithDebInfo"); - tempPath = filepath; - tempPath += "Deployment/"; - tempPath += filename; + tempPath = cmStrCat(filepath, "Deployment/", filename); attempted.push_back(tempPath); attemptedConfigs.emplace_back("Deployment"); - tempPath = filepath; - tempPath += "Development/"; - tempPath += filename; + tempPath = cmStrCat(filepath, "Development/", filename); attempted.push_back(tempPath); attemptedConfigs.emplace_back("Deployment"); } @@ -1624,8 +1625,8 @@ std::string cmCTestTestHandler::FindExecutable( // then try with the exe extension else { failed.push_back(attempted[ai]); - tempPath = attempted[ai]; - tempPath += cmSystemTools::GetExecutableExtension(); + tempPath = + cmStrCat(attempted[ai], cmSystemTools::GetExecutableExtension()); if (cmSystemTools::FileExists(tempPath) && !cmSystemTools::FileIsDirectory(tempPath)) { fullPath = cmSystemTools::CollapseFullPath(tempPath); @@ -1682,36 +1683,34 @@ void cmCTestTestHandler::GetListOfTests() cm.GetCurrentSnapshot().SetDefaultDefinitions(); cmGlobalGenerator gg(&cm); cmMakefile mf(&gg, cm.GetCurrentSnapshot()); - mf.AddDefinition("CTEST_CONFIGURATION_TYPE", - this->CTest->GetConfigType().c_str()); + mf.AddDefinition("CTEST_CONFIGURATION_TYPE", this->CTest->GetConfigType()); // Add handler for ADD_TEST - cmCTestAddTestCommand* newCom1 = new cmCTestAddTestCommand; + auto newCom1 = cm::make_unique<cmCTestAddTestCommand>(); newCom1->TestHandler = this; - cm.GetState()->AddBuiltinCommand("add_test", newCom1); + cm.GetState()->AddBuiltinCommand("add_test", std::move(newCom1)); // Add handler for SUBDIRS - cmCTestSubdirCommand* newCom2 = new cmCTestSubdirCommand; + auto newCom2 = cm::make_unique<cmCTestSubdirCommand>(); newCom2->TestHandler = this; - cm.GetState()->AddBuiltinCommand("subdirs", newCom2); + cm.GetState()->AddBuiltinCommand("subdirs", std::move(newCom2)); // Add handler for ADD_SUBDIRECTORY - cmCTestAddSubdirectoryCommand* newCom3 = new cmCTestAddSubdirectoryCommand; + auto newCom3 = cm::make_unique<cmCTestAddSubdirectoryCommand>(); newCom3->TestHandler = this; - cm.GetState()->AddBuiltinCommand("add_subdirectory", newCom3); + cm.GetState()->AddBuiltinCommand("add_subdirectory", std::move(newCom3)); // Add handler for SET_TESTS_PROPERTIES - cmCTestSetTestsPropertiesCommand* newCom4 = - new cmCTestSetTestsPropertiesCommand; + auto newCom4 = cm::make_unique<cmCTestSetTestsPropertiesCommand>(); newCom4->TestHandler = this; - cm.GetState()->AddBuiltinCommand("set_tests_properties", newCom4); + cm.GetState()->AddBuiltinCommand("set_tests_properties", std::move(newCom4)); // Add handler for SET_DIRECTORY_PROPERTIES cm.GetState()->RemoveBuiltinCommand("set_directory_properties"); - cmCTestSetDirectoryPropertiesCommand* newCom5 = - new cmCTestSetDirectoryPropertiesCommand; + auto newCom5 = cm::make_unique<cmCTestSetDirectoryPropertiesCommand>(); newCom5->TestHandler = this; - cm.GetState()->AddBuiltinCommand("set_directory_properties", newCom5); + cm.GetState()->AddBuiltinCommand("set_directory_properties", + std::move(newCom5)); const char* testFilename; if (cmSystemTools::FileExists("CTestTestfile.cmake")) { @@ -2150,7 +2149,7 @@ bool cmCTestTestHandler::SetTestsProperties( if (key == "_BACKTRACE_TRIPLES") { std::vector<std::string> triples; // allow empty args in the triples - cmSystemTools::ExpandListArgument(val, triples, true); + cmExpandList(val, triples, true); // Ensure we have complete triples otherwise the data is corrupt. if (triples.size() % 3 == 0) { @@ -2163,8 +2162,7 @@ bool cmCTestTestHandler::SetTestsProperties( cmListFileContext fc; fc.FilePath = triples[i - 3]; long line = 0; - if (!cmSystemTools::StringToLong(triples[i - 2].c_str(), - &line)) { + if (!cmStrToLong(triples[i - 2], &line)) { line = 0; } fc.Line = line; @@ -2174,38 +2172,34 @@ bool cmCTestTestHandler::SetTestsProperties( } } if (key == "WILL_FAIL") { - rt.WillFail = cmSystemTools::IsOn(val); + rt.WillFail = cmIsOn(val); } if (key == "DISABLED") { - rt.Disabled = cmSystemTools::IsOn(val); + rt.Disabled = cmIsOn(val); } if (key == "ATTACHED_FILES") { - cmSystemTools::ExpandListArgument(val, rt.AttachedFiles); + cmExpandList(val, rt.AttachedFiles); } if (key == "ATTACHED_FILES_ON_FAIL") { - cmSystemTools::ExpandListArgument(val, rt.AttachOnFail); + cmExpandList(val, rt.AttachOnFail); } if (key == "RESOURCE_LOCK") { - std::vector<std::string> lval; - cmSystemTools::ExpandListArgument(val, lval); + std::vector<std::string> lval = cmExpandedList(val); rt.LockedResources.insert(lval.begin(), lval.end()); } if (key == "FIXTURES_SETUP") { - std::vector<std::string> lval; - cmSystemTools::ExpandListArgument(val, lval); + std::vector<std::string> lval = cmExpandedList(val); rt.FixturesSetup.insert(lval.begin(), lval.end()); } if (key == "FIXTURES_CLEANUP") { - std::vector<std::string> lval; - cmSystemTools::ExpandListArgument(val, lval); + std::vector<std::string> lval = cmExpandedList(val); rt.FixturesCleanup.insert(lval.begin(), lval.end()); } if (key == "FIXTURES_REQUIRED") { - std::vector<std::string> lval; - cmSystemTools::ExpandListArgument(val, lval); + std::vector<std::string> lval = cmExpandedList(val); rt.FixturesRequired.insert(lval.begin(), lval.end()); } @@ -2217,18 +2211,23 @@ bool cmCTestTestHandler::SetTestsProperties( rt.Cost = static_cast<float>(atof(val.c_str())); } if (key == "REQUIRED_FILES") { - cmSystemTools::ExpandListArgument(val, rt.RequiredFiles); + cmExpandList(val, rt.RequiredFiles); } if (key == "RUN_SERIAL") { - rt.RunSerial = cmSystemTools::IsOn(val); + rt.RunSerial = cmIsOn(val); } if (key == "FAIL_REGULAR_EXPRESSION") { - std::vector<std::string> lval; - cmSystemTools::ExpandListArgument(val, lval); + std::vector<std::string> lval = cmExpandedList(val); for (std::string const& cr : lval) { rt.ErrorRegularExpressions.emplace_back(cr, cr); } } + if (key == "SKIP_REGULAR_EXPRESSION") { + std::vector<std::string> lval = cmExpandedList(val); + for (std::string const& cr : lval) { + rt.SkipRegularExpressions.emplace_back(cr, cr); + } + } if (key == "PROCESSORS") { rt.Processors = atoi(val.c_str()); if (rt.Processors < 1) { @@ -2236,7 +2235,7 @@ bool cmCTestTestHandler::SetTestsProperties( } } if (key == "PROCESSOR_AFFINITY") { - rt.WantAffinity = cmSystemTools::IsOn(val); + rt.WantAffinity = cmIsOn(val); } if (key == "SKIP_RETURN_CODE") { rt.SkipReturnCode = atoi(val.c_str()); @@ -2245,14 +2244,13 @@ bool cmCTestTestHandler::SetTestsProperties( } } if (key == "DEPENDS") { - cmSystemTools::ExpandListArgument(val, rt.Depends); + cmExpandList(val, rt.Depends); } if (key == "ENVIRONMENT") { - cmSystemTools::ExpandListArgument(val, rt.Environment); + cmExpandList(val, rt.Environment); } if (key == "LABELS") { - std::vector<std::string> Labels; - cmSystemTools::ExpandListArgument(val, Labels); + std::vector<std::string> Labels = cmExpandedList(val); rt.Labels.insert(rt.Labels.end(), Labels.begin(), Labels.end()); // sort the array std::sort(rt.Labels.begin(), rt.Labels.end()); @@ -2272,8 +2270,7 @@ bool cmCTestTestHandler::SetTestsProperties( } } if (key == "PASS_REGULAR_EXPRESSION") { - std::vector<std::string> lval; - cmSystemTools::ExpandListArgument(val, lval); + std::vector<std::string> lval = cmExpandedList(val); for (std::string const& cr : lval) { rt.RequiredRegularExpressions.emplace_back(cr, cr); } @@ -2282,16 +2279,14 @@ bool cmCTestTestHandler::SetTestsProperties( rt.Directory = val; } if (key == "TIMEOUT_AFTER_MATCH") { - std::vector<std::string> propArgs; - cmSystemTools::ExpandListArgument(val, propArgs); + std::vector<std::string> propArgs = cmExpandedList(val); if (propArgs.size() != 2) { cmCTestLog(this->CTest, WARNING, "TIMEOUT_AFTER_MATCH expects two arguments, found " << propArgs.size() << std::endl); } else { rt.AlternateTimeout = cmDuration(atof(propArgs[0].c_str())); - std::vector<std::string> lval; - cmSystemTools::ExpandListArgument(propArgs[1], lval); + std::vector<std::string> lval = cmExpandedList(propArgs[1]); for (std::string const& cr : lval) { rt.TimeoutRegularExpressions.emplace_back(cr, cr); } @@ -2333,8 +2328,7 @@ bool cmCTestTestHandler::SetDirectoryProperties( std::string cwd = cmSystemTools::GetCurrentWorkingDirectory(); if (cwd == rt.Directory) { if (key == "LABELS") { - std::vector<std::string> DirectoryLabels; - cmSystemTools::ExpandListArgument(val, DirectoryLabels); + std::vector<std::string> DirectoryLabels = cmExpandedList(val); rt.Labels.insert(rt.Labels.end(), DirectoryLabels.begin(), DirectoryLabels.end()); diff --git a/Source/CTest/cmCTestTestHandler.h b/Source/CTest/cmCTestTestHandler.h index 7f3f5e4..9345185 100644 --- a/Source/CTest/cmCTestTestHandler.h +++ b/Source/CTest/cmCTestTestHandler.h @@ -118,6 +118,8 @@ public: std::vector<std::pair<cmsys::RegularExpression, std::string>> RequiredRegularExpressions; std::vector<std::pair<cmsys::RegularExpression, std::string>> + SkipRegularExpressions; + std::vector<std::pair<cmsys::RegularExpression, std::string>> TimeoutRegularExpressions; std::map<std::string, std::string> Measurements; bool IsInBasedOnREOptions; @@ -189,12 +191,25 @@ public: typedef std::vector<cmCTestTestProperties> ListOfTests; protected: + typedef std::set<cmCTestTestHandler::cmCTestTestResult, + cmCTestTestResultLess> + SetOfTests; + // compute a final test list virtual int PreProcessHandler(); virtual int PostProcessHandler(); virtual void GenerateTestCommand(std::vector<std::string>& args, int test); int ExecuteCommands(std::vector<std::string>& vec); + bool ProcessOptions(); + void LogTestSummary(const std::vector<std::string>& passed, + const std::vector<std::string>& failed, + const cmDuration& durationInSecs); + void LogDisabledTests(const std::vector<cmCTestTestResult>& disabledTests); + void LogFailedTests(const std::vector<std::string>& failed, + const SetOfTests& resultsSet); + bool GenerateXML(); + void WriteTestResultHeader(cmXMLWriter& xml, cmCTestTestResult const& result); void WriteTestResultFooter(cmXMLWriter& xml, diff --git a/Source/CTest/cmCTestUpdateCommand.h b/Source/CTest/cmCTestUpdateCommand.h index 3b2f3e1..55c4b80 100644 --- a/Source/CTest/cmCTestUpdateCommand.h +++ b/Source/CTest/cmCTestUpdateCommand.h @@ -6,11 +6,14 @@ #include "cmConfigure.h" // IWYU pragma: keep #include "cmCTestHandlerCommand.h" +#include "cmCommand.h" #include <string> +#include <utility> + +#include "cm_memory.hxx" class cmCTestGenericHandler; -class cmCommand; /** \class cmCTestUpdate * \brief Run a ctest script @@ -25,12 +28,12 @@ public: /** * This is a virtual constructor for the command. */ - cmCommand* Clone() override + std::unique_ptr<cmCommand> Clone() override { - cmCTestUpdateCommand* ni = new cmCTestUpdateCommand; + auto ni = cm::make_unique<cmCTestUpdateCommand>(); ni->CTest = this->CTest; ni->CTestScriptHandler = this->CTestScriptHandler; - return ni; + return std::unique_ptr<cmCommand>(std::move(ni)); } /** diff --git a/Source/CTest/cmCTestUpdateHandler.cxx b/Source/CTest/cmCTestUpdateHandler.cxx index 5cfc4a7..a6a3542 100644 --- a/Source/CTest/cmCTestUpdateHandler.cxx +++ b/Source/CTest/cmCTestUpdateHandler.cxx @@ -2,7 +2,6 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmCTestUpdateHandler.h" -#include "cmAlgorithms.h" #include "cmCLocaleEnvironmentScope.h" #include "cmCTest.h" #include "cmCTestBZR.h" @@ -13,14 +12,16 @@ #include "cmCTestSVN.h" #include "cmCTestVC.h" #include "cmGeneratedFileStream.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmVersion.h" #include "cmXMLWriter.h" #include <chrono> -#include <memory> // IWYU pragma: keep #include <sstream> +#include "cm_memory.hxx" + static const char* cmCTestUpdateHandlerUpdateStrings[] = { "Unknown", "CVS", "SVN", "BZR", "GIT", "HG", "P4" }; @@ -266,33 +267,27 @@ int cmCTestUpdateHandler::DetectVCS(const char* dir) if (cmSystemTools::FileExists(sourceDirectory)) { return cmCTestUpdateHandler::e_SVN; } - sourceDirectory = dir; - sourceDirectory += "/CVS"; + sourceDirectory = cmStrCat(dir, "/CVS"); if (cmSystemTools::FileExists(sourceDirectory)) { return cmCTestUpdateHandler::e_CVS; } - sourceDirectory = dir; - sourceDirectory += "/.bzr"; + sourceDirectory = cmStrCat(dir, "/.bzr"); if (cmSystemTools::FileExists(sourceDirectory)) { return cmCTestUpdateHandler::e_BZR; } - sourceDirectory = dir; - sourceDirectory += "/.git"; + sourceDirectory = cmStrCat(dir, "/.git"); if (cmSystemTools::FileExists(sourceDirectory)) { return cmCTestUpdateHandler::e_GIT; } - sourceDirectory = dir; - sourceDirectory += "/.hg"; + sourceDirectory = cmStrCat(dir, "/.hg"); if (cmSystemTools::FileExists(sourceDirectory)) { return cmCTestUpdateHandler::e_HG; } - sourceDirectory = dir; - sourceDirectory += "/.p4"; + sourceDirectory = cmStrCat(dir, "/.p4"); if (cmSystemTools::FileExists(sourceDirectory)) { return cmCTestUpdateHandler::e_P4; } - sourceDirectory = dir; - sourceDirectory += "/.p4config"; + sourceDirectory = cmStrCat(dir, "/.p4config"); if (cmSystemTools::FileExists(sourceDirectory)) { return cmCTestUpdateHandler::e_P4; } diff --git a/Source/CTest/cmCTestUploadCommand.h b/Source/CTest/cmCTestUploadCommand.h index 0d3b06e..2bb072f 100644 --- a/Source/CTest/cmCTestUploadCommand.h +++ b/Source/CTest/cmCTestUploadCommand.h @@ -6,12 +6,15 @@ #include "cmConfigure.h" // IWYU pragma: keep #include "cmCTestHandlerCommand.h" +#include "cmCommand.h" #include <set> #include <string> +#include <utility> + +#include "cm_memory.hxx" class cmCTestGenericHandler; -class cmCommand; /** \class cmCTestUpload * \brief Run a ctest script @@ -25,12 +28,12 @@ public: /** * This is a virtual constructor for the command. */ - cmCommand* Clone() override + std::unique_ptr<cmCommand> Clone() override { - cmCTestUploadCommand* ni = new cmCTestUploadCommand; + auto ni = cm::make_unique<cmCTestUploadCommand>(); ni->CTest = this->CTest; ni->CTestScriptHandler = this->CTestScriptHandler; - return ni; + return std::unique_ptr<cmCommand>(std::move(ni)); } /** diff --git a/Source/CTest/cmCTestVC.cxx b/Source/CTest/cmCTestVC.cxx index eea41cf..773886d 100644 --- a/Source/CTest/cmCTestVC.cxx +++ b/Source/CTest/cmCTestVC.cxx @@ -3,6 +3,7 @@ #include "cmCTestVC.h" #include "cmCTest.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmXMLWriter.h" @@ -152,8 +153,7 @@ bool cmCTestVC::Update() // if update version only is on then do not actually update, // just note the current version and finish - if (!cmSystemTools::IsOn( - this->CTest->GetCTestConfiguration("UpdateVersionOnly"))) { + if (!cmIsOn(this->CTest->GetCTestConfiguration("UpdateVersionOnly"))) { result = this->NoteOldRevision() && result; this->Log << "--- Begin Update ---\n"; result = this->UpdateImpl() && result; diff --git a/Source/CTest/cmParseBlanketJSCoverage.cxx b/Source/CTest/cmParseBlanketJSCoverage.cxx index 63d6a15..b74decb 100644 --- a/Source/CTest/cmParseBlanketJSCoverage.cxx +++ b/Source/CTest/cmParseBlanketJSCoverage.cxx @@ -110,7 +110,8 @@ cmParseBlanketJSCoverage::cmParseBlanketJSCoverage( { } -bool cmParseBlanketJSCoverage::LoadCoverageData(std::vector<std::string> files) +bool cmParseBlanketJSCoverage::LoadCoverageData( + std::vector<std::string> const& files) { cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Found " << files.size() << " Files" << std::endl, diff --git a/Source/CTest/cmParseBlanketJSCoverage.h b/Source/CTest/cmParseBlanketJSCoverage.h index 696121f..cd1b225 100644 --- a/Source/CTest/cmParseBlanketJSCoverage.h +++ b/Source/CTest/cmParseBlanketJSCoverage.h @@ -29,7 +29,7 @@ class cmParseBlanketJSCoverage public: cmParseBlanketJSCoverage(cmCTestCoverageHandlerContainer& cont, cmCTest* ctest); - bool LoadCoverageData(std::vector<std::string> files); + bool LoadCoverageData(std::vector<std::string> const& files); // Read the JSON output bool ReadJSONFile(std::string const& file); diff --git a/Source/CTest/cmParseCacheCoverage.cxx b/Source/CTest/cmParseCacheCoverage.cxx index ca1fe70..cd2bb1a 100644 --- a/Source/CTest/cmParseCacheCoverage.cxx +++ b/Source/CTest/cmParseCacheCoverage.cxx @@ -2,6 +2,7 @@ #include "cmCTest.h" #include "cmCTestCoverageHandler.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmsys/Directory.hxx" @@ -30,9 +31,7 @@ bool cmParseCacheCoverage::LoadCoverageData(const char* d) for (i = 0; i < numf; i++) { std::string file = dir.GetFile(i); if (file != "." && file != ".." && !cmSystemTools::FileIsDirectory(file)) { - std::string path = d; - path += "/"; - path += file; + std::string path = cmStrCat(d, '/', file); if (cmSystemTools::GetFilenameLastExtension(path) == ".cmcov") { if (!this->ReadCMCovFile(path.c_str())) { return false; diff --git a/Source/CTest/cmParseCoberturaCoverage.cxx b/Source/CTest/cmParseCoberturaCoverage.cxx index 848a034..e0186c9 100644 --- a/Source/CTest/cmParseCoberturaCoverage.cxx +++ b/Source/CTest/cmParseCoberturaCoverage.cxx @@ -2,6 +2,7 @@ #include "cmCTest.h" #include "cmCTestCoverageHandler.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmXMLParser.h" @@ -75,7 +76,7 @@ protected: // Check if this is a path that is relative to our source or // binary directories. for (std::string const& filePath : FilePaths) { - finalpath = filePath + "/" + filename; + finalpath = cmStrCat(filePath, "/", filename); if (cmSystemTools::FileExists(finalpath)) { this->CurFileName = finalpath; break; @@ -86,7 +87,7 @@ protected: cmsys::ifstream fin(this->CurFileName.c_str()); if (this->CurFileName.empty() || !fin) { this->CurFileName = - this->Coverage.BinaryDir + "/" + atts[tagCount + 1]; + cmStrCat(this->Coverage.BinaryDir, "/", atts[tagCount + 1]); fin.open(this->CurFileName.c_str()); if (!fin) { cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, diff --git a/Source/CTest/cmParseGTMCoverage.cxx b/Source/CTest/cmParseGTMCoverage.cxx index 0722753..621ca79 100644 --- a/Source/CTest/cmParseGTMCoverage.cxx +++ b/Source/CTest/cmParseGTMCoverage.cxx @@ -1,8 +1,8 @@ #include "cmParseGTMCoverage.h" -#include "cmAlgorithms.h" #include "cmCTest.h" #include "cmCTestCoverageHandler.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmsys/Directory.hxx" @@ -31,9 +31,7 @@ bool cmParseGTMCoverage::LoadCoverageData(const char* d) for (i = 0; i < numf; i++) { std::string file = dir.GetFile(i); if (file != "." && file != ".." && !cmSystemTools::FileIsDirectory(file)) { - std::string path = d; - path += "/"; - path += file; + std::string path = cmStrCat(d, '/', file); if (cmSystemTools::GetFilenameLastExtension(path) == ".mcov") { if (!this->ReadMCovFile(path.c_str())) { return false; diff --git a/Source/CTest/cmParseJacocoCoverage.cxx b/Source/CTest/cmParseJacocoCoverage.cxx index b78142a..374acad 100644 --- a/Source/CTest/cmParseJacocoCoverage.cxx +++ b/Source/CTest/cmParseJacocoCoverage.cxx @@ -2,6 +2,7 @@ #include "cmCTest.h" #include "cmCTestCoverageHandler.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmXMLParser.h" @@ -103,9 +104,7 @@ protected: std::string const& baseDir) { // Search for the file in the baseDir and its subdirectories. - std::string packageGlob = baseDir; - packageGlob += "/"; - packageGlob += fileName; + std::string packageGlob = cmStrCat(baseDir, '/', fileName); cmsys::Glob gl; gl.RecurseOn(); gl.RecurseThroughSymlinksOn(); @@ -118,7 +117,7 @@ protected: // Check if any of the locations found match our package. for (std::string const& f : files) { std::string dir = cmsys::SystemTools::GetParentDirectory(f); - if (cmsys::SystemTools::StringEndsWith(dir, this->PackageName.c_str())) { + if (cmHasSuffix(dir, this->PackageName)) { cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Found package directory for " << fileName << ": " << dir << std::endl, diff --git a/Source/CTest/cmParseMumpsCoverage.cxx b/Source/CTest/cmParseMumpsCoverage.cxx index 4a81ee4..afd7dc3 100644 --- a/Source/CTest/cmParseMumpsCoverage.cxx +++ b/Source/CTest/cmParseMumpsCoverage.cxx @@ -2,6 +2,7 @@ #include "cmCTest.h" #include "cmCTestCoverageHandler.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmsys/FStream.hxx" @@ -107,8 +108,7 @@ bool cmParseMumpsCoverage::LoadPackages(const char* d) { cmsys::Glob glob; glob.RecurseOn(); - std::string pat = d; - pat += "/*.m"; + std::string pat = cmStrCat(d, "/*.m"); glob.FindFiles(pat); for (std::string& file : glob.GetFiles()) { std::string name = cmSystemTools::GetFilenameName(file); diff --git a/Source/CTest/cmParsePHPCoverage.cxx b/Source/CTest/cmParsePHPCoverage.cxx index a6e65c9..870e222 100644 --- a/Source/CTest/cmParsePHPCoverage.cxx +++ b/Source/CTest/cmParsePHPCoverage.cxx @@ -2,6 +2,7 @@ #include "cmCTest.h" #include "cmCTestCoverageHandler.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmsys/Directory.hxx" @@ -210,9 +211,7 @@ bool cmParsePHPCoverage::ReadPHPCoverageDirectory(const char* d) for (i = 0; i < numf; i++) { std::string file = dir.GetFile(i); if (file != "." && file != ".." && !cmSystemTools::FileIsDirectory(file)) { - std::string path = d; - path += "/"; - path += file; + std::string path = cmStrCat(d, '/', file); if (!this->ReadPHPData(path.c_str())) { return false; } diff --git a/Source/CTest/cmProcess.cxx b/Source/CTest/cmProcess.cxx index 7a3b82e..61d2ed3 100644 --- a/Source/CTest/cmProcess.cxx +++ b/Source/CTest/cmProcess.cxx @@ -7,6 +7,7 @@ #include "cmCTestRunTest.h" #include "cmCTestTestHandler.h" #include "cmGetPipes.h" +#include "cmStringAlgorithms.h" #include "cmsys/Process.h" #include <iostream> @@ -694,8 +695,7 @@ std::string cmProcess::GetExitExceptionString() # endif # endif default: - exception_str = "Signal "; - exception_str += std::to_string(this->Signal); + exception_str = cmStrCat("Signal ", this->Signal); } #endif return exception_str; 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 c1dd591..f450a1c 100644 --- a/Source/CursesDialog/cmCursesCacheEntryComposite.cxx +++ b/Source/CursesDialog/cmCursesCacheEntryComposite.cxx @@ -11,6 +11,7 @@ #include "cmCursesWidget.h" #include "cmState.h" #include "cmStateTypes.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmake.h" @@ -49,7 +50,7 @@ cmCursesCacheEntryComposite::cmCursesCacheEntryComposite( switch (cm->GetState()->GetCacheEntryType(key)) { case cmStateEnums::BOOL: this->Entry = new cmCursesBoolWidget(this->EntryWidth, 1, 1, 1); - if (cmSystemTools::IsOn(value)) { + if (cmIsOn(value)) { static_cast<cmCursesBoolWidget*>(this->Entry)->SetValueAsBool(true); } else { static_cast<cmCursesBoolWidget*>(this->Entry)->SetValueAsBool(false); @@ -70,8 +71,7 @@ cmCursesCacheEntryComposite::cmCursesCacheEntryComposite( cmCursesOptionsWidget* ow = new cmCursesOptionsWidget(this->EntryWidth, 1, 1, 1); this->Entry = ow; - std::vector<std::string> options; - cmSystemTools::ExpandListArgument(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 028e852..1b25716 100644 --- a/Source/CursesDialog/cmCursesMainForm.cxx +++ b/Source/CursesDialog/cmCursesMainForm.cxx @@ -13,6 +13,7 @@ #include "cmCursesWidget.h" #include "cmState.h" #include "cmStateTypes.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmVersion.h" #include "cmake.h" @@ -47,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 = ""; @@ -319,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) { @@ -390,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 || @@ -508,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); @@ -551,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, @@ -580,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); @@ -609,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()) { @@ -696,7 +703,7 @@ void cmCursesMainForm::FixValue(cmStateEnums::CacheEntryType type, cmSystemTools::ConvertToUnixSlashes(out); } if (type == cmStateEnums::BOOL) { - if (cmSystemTools::IsOff(out)) { + if (cmIsOff(out)) { out = "OFF"; } else { out = "ON"; @@ -706,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/LexerParser/cmCommandArgumentParser.cxx b/Source/LexerParser/cmCommandArgumentParser.cxx index b965b32..ae7fb42 100644 --- a/Source/LexerParser/cmCommandArgumentParser.cxx +++ b/Source/LexerParser/cmCommandArgumentParser.cxx @@ -1,8 +1,9 @@ -/* A Bison parser, made by GNU Bison 3.0.4. */ +/* A Bison parser, made by GNU Bison 3.3.2. */ /* Bison implementation for Yacc-like parsers in C - Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc. + Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2019 Free Software Foundation, + Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -40,11 +41,14 @@ define necessary library symbols; they are noted "INFRINGES ON USER NAME SPACE" below. */ +/* Undocumented macros, especially those whose name start with YY_, + are private implementation details. Do not rely on them. */ + /* Identify Bison output. */ #define YYBISON 1 /* Bison version. */ -#define YYBISON_VERSION "3.0.4" +#define YYBISON_VERSION "3.3.2" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" @@ -67,8 +71,8 @@ #define yynerrs cmCommandArgument_yynerrs -/* Copy the first part of user declarations. */ -#line 1 "cmCommandArgumentParser.y" /* yacc.c:339 */ +/* First part of user prologue. */ +#line 1 "cmCommandArgumentParser.y" /* yacc.c:337 */ /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying file Copyright.txt or https://cmake.org/licensing for details. */ @@ -130,13 +134,16 @@ static void cmCommandArgument_yyerror(yyscan_t yyscanner, const char* message); # pragma GCC diagnostic ignored "-Wconversion" #endif -#line 134 "cmCommandArgumentParser.cxx" /* yacc.c:339 */ - +#line 138 "cmCommandArgumentParser.cxx" /* yacc.c:337 */ # ifndef YY_NULLPTR -# if defined __cplusplus && 201103L <= __cplusplus -# define YY_NULLPTR nullptr +# if defined __cplusplus +# if 201103L <= __cplusplus +# define YY_NULLPTR nullptr +# else +# define YY_NULLPTR 0 +# endif # else -# define YY_NULLPTR 0 +# define YY_NULLPTR ((void*)0) # endif # endif @@ -201,9 +208,7 @@ int cmCommandArgument_yyparse (yyscan_t yyscanner); #endif /* !YY_CMCOMMANDARGUMENT_YY_CMCOMMANDARGUMENTPARSERTOKENS_H_INCLUDED */ -/* Copy the second part of user declarations. */ -#line 207 "cmCommandArgumentParser.cxx" /* yacc.c:358 */ #ifdef short # undef short @@ -224,13 +229,13 @@ typedef signed char yytype_int8; #ifdef YYTYPE_UINT16 typedef YYTYPE_UINT16 yytype_uint16; #else -typedef unsigned short int yytype_uint16; +typedef unsigned short yytype_uint16; #endif #ifdef YYTYPE_INT16 typedef YYTYPE_INT16 yytype_int16; #else -typedef short int yytype_int16; +typedef short yytype_int16; #endif #ifndef YYSIZE_T @@ -242,7 +247,7 @@ typedef short int yytype_int16; # include <stddef.h> /* INFRINGES ON USER NAME SPACE */ # define YYSIZE_T size_t # else -# define YYSIZE_T unsigned int +# define YYSIZE_T unsigned # endif #endif @@ -278,15 +283,6 @@ typedef short int yytype_int16; # define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__)) #endif -#if !defined _Noreturn \ - && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112) -# if defined _MSC_VER && 1200 <= _MSC_VER -# define _Noreturn __declspec (noreturn) -# else -# define _Noreturn YY_ATTRIBUTE ((__noreturn__)) -# endif -#endif - /* Suppress unused-variable warnings by "using" E. */ #if ! defined lint || defined __GNUC__ # define YYUSE(E) ((void) (E)) @@ -294,7 +290,7 @@ typedef short int yytype_int16; # define YYUSE(E) /* empty */ #endif -#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ +#if defined __GNUC__ && ! defined __ICC && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ /* Suppress an incorrect diagnostic about yylval being uninitialized. */ # define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ _Pragma ("GCC diagnostic push") \ @@ -456,16 +452,16 @@ union yyalloc /* YYNSTATES -- Number of states. */ #define YYNSTATES 33 -/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned - by yylex, with out-of-bounds checking. */ #define YYUNDEFTOK 2 #define YYMAXUTOK 269 +/* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM + as returned by yylex, with out-of-bounds checking. */ #define YYTRANSLATE(YYX) \ - ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + ((unsigned) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) /* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM - as returned by yylex, without out-of-bounds checking. */ + as returned by yylex. */ static const yytype_uint8 yytranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -513,7 +509,7 @@ static const yytype_uint8 yyrline[] = static const char *const yytname[] = { "$end", "error", "$undefined", "cal_ENVCURLY", "cal_NCURLY", - "cal_DCURLY", "\"$\"", "\"{\"", "\"}\"", "cal_NAME", R"("\\")", + "cal_DCURLY", "\"$\"", "\"{\"", "\"}\"", "cal_NAME", "\"\\\\\"", "cal_SYMBOL", "\"@\"", "cal_ERROR", "cal_ATNAME", "$accept", "Start", "GoalWithOptionalBackSlash", "Goal", "String", "OuterText", "Variable", "EnvVarName", "MultipleIds", "ID", YY_NULLPTR @@ -633,22 +629,22 @@ static const yytype_uint8 yyr2[] = #define YYRECOVERING() (!!yyerrstatus) -#define YYBACKUP(Token, Value) \ -do \ - if (yychar == YYEMPTY) \ - { \ - yychar = (Token); \ - yylval = (Value); \ - YYPOPSTACK (yylen); \ - yystate = *yyssp; \ - goto yybackup; \ - } \ - else \ - { \ - yyerror (yyscanner, YY_("syntax error: cannot back up")); \ - YYERROR; \ - } \ -while (0) +#define YYBACKUP(Token, Value) \ + do \ + if (yychar == YYEMPTY) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + YYPOPSTACK (yylen); \ + yystate = *yyssp; \ + goto yybackup; \ + } \ + else \ + { \ + yyerror (yyscanner, YY_("syntax error: cannot back up")); \ + YYERROR; \ + } \ + while (0) /* Error token number */ #define YYTERROR 1 @@ -688,38 +684,38 @@ do { \ } while (0) -/*----------------------------------------. -| Print this symbol's value on YYOUTPUT. | -`----------------------------------------*/ +/*-----------------------------------. +| Print this symbol's value on YYO. | +`-----------------------------------*/ static void -yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, yyscan_t yyscanner) +yy_symbol_value_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep, yyscan_t yyscanner) { - FILE *yyo = yyoutput; - YYUSE (yyo); + FILE *yyoutput = yyo; + YYUSE (yyoutput); YYUSE (yyscanner); if (!yyvaluep) return; # ifdef YYPRINT if (yytype < YYNTOKENS) - YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); + YYPRINT (yyo, yytoknum[yytype], *yyvaluep); # endif YYUSE (yytype); } -/*--------------------------------. -| Print this symbol on YYOUTPUT. | -`--------------------------------*/ +/*---------------------------. +| Print this symbol on YYO. | +`---------------------------*/ static void -yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, yyscan_t yyscanner) +yy_symbol_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep, yyscan_t yyscanner) { - YYFPRINTF (yyoutput, "%s %s (", + YYFPRINTF (yyo, "%s %s (", yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]); - yy_symbol_value_print (yyoutput, yytype, yyvaluep, yyscanner); - YYFPRINTF (yyoutput, ")"); + yy_symbol_value_print (yyo, yytype, yyvaluep, yyscanner); + YYFPRINTF (yyo, ")"); } /*------------------------------------------------------------------. @@ -753,7 +749,7 @@ do { \ static void yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule, yyscan_t yyscanner) { - unsigned long int yylno = yyrline[yyrule]; + unsigned long yylno = yyrline[yyrule]; int yynrhs = yyr2[yyrule]; int yyi; YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", @@ -764,7 +760,7 @@ yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule, yyscan_t yysca YYFPRINTF (stderr, " $%d = ", yyi + 1); yy_symbol_print (stderr, yystos[yyssp[yyi + 1 - yynrhs]], - &(yyvsp[(yyi + 1) - (yynrhs)]) + &yyvsp[(yyi + 1) - (yynrhs)] , yyscanner); YYFPRINTF (stderr, "\n"); } @@ -868,7 +864,10 @@ yytnamerr (char *yyres, const char *yystr) case '\\': if (*++yyp != '\\') goto do_not_strip_quotes; - /* Fall through. */ + else + goto append; + + append: default: if (yyres) yyres[yyn] = *yyp; @@ -886,7 +885,7 @@ yytnamerr (char *yyres, const char *yystr) if (! yyres) return yystrlen (yystr); - return yystpcpy (yyres, yystr) - yyres; + return (YYSIZE_T) (yystpcpy (yyres, yystr) - yyres); } # endif @@ -964,10 +963,10 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, yyarg[yycount++] = yytname[yyx]; { YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]); - if (! (yysize <= yysize1 - && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) + if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM) + yysize = yysize1; + else return 2; - yysize = yysize1; } } } @@ -979,6 +978,7 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, case N: \ yyformat = S; \ break + default: /* Avoid compiler warnings. */ YYCASE_(0, YY_("syntax error")); YYCASE_(1, YY_("syntax error, unexpected %s")); YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); @@ -990,9 +990,10 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, { YYSIZE_T yysize1 = yysize + yystrlen (yyformat); - if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) + if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM) + yysize = yysize1; + else return 2; - yysize = yysize1; } if (*yymsg_alloc < yysize) @@ -1123,23 +1124,31 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); yychar = YYEMPTY; /* Cause a token to be read. */ goto yysetstate; + /*------------------------------------------------------------. -| yynewstate -- Push a new state, which is found in yystate. | +| yynewstate -- push a new state, which is found in yystate. | `------------------------------------------------------------*/ - yynewstate: +yynewstate: /* In all cases, when you get here, the value and location stacks have just been pushed. So pushing a state here evens the stacks. */ yyssp++; - yysetstate: - *yyssp = yystate; + +/*--------------------------------------------------------------------. +| yynewstate -- set current state (the top of the stack) to yystate. | +`--------------------------------------------------------------------*/ +yysetstate: + *yyssp = (yytype_int16) yystate; if (yyss + yystacksize - 1 <= yyssp) +#if !defined yyoverflow && !defined YYSTACK_RELOCATE + goto yyexhaustedlab; +#else { /* Get the current used size of the three stacks, in elements. */ - YYSIZE_T yysize = yyssp - yyss + 1; + YYSIZE_T yysize = (YYSIZE_T) (yyssp - yyss + 1); -#ifdef yyoverflow +# if defined yyoverflow { /* Give user a chance to reallocate the stack. Use copies of these so that the &'s don't force the real ones into @@ -1155,14 +1164,10 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); &yyss1, yysize * sizeof (*yyssp), &yyvs1, yysize * sizeof (*yyvsp), &yystacksize); - yyss = yyss1; yyvs = yyvs1; } -#else /* no yyoverflow */ -# ifndef YYSTACK_RELOCATE - goto yyexhaustedlab; -# else +# else /* defined YYSTACK_RELOCATE */ /* Extend the stack our own way. */ if (YYMAXDEPTH <= yystacksize) goto yyexhaustedlab; @@ -1178,22 +1183,22 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); goto yyexhaustedlab; YYSTACK_RELOCATE (yyss_alloc, yyss); YYSTACK_RELOCATE (yyvs_alloc, yyvs); -# undef YYSTACK_RELOCATE +# undef YYSTACK_RELOCATE if (yyss1 != yyssa) YYSTACK_FREE (yyss1); } # endif -#endif /* no yyoverflow */ yyssp = yyss + yysize - 1; yyvsp = yyvs + yysize - 1; YYDPRINTF ((stderr, "Stack size increased to %lu\n", - (unsigned long int) yystacksize)); + (unsigned long) yystacksize)); if (yyss + yystacksize - 1 <= yyssp) YYABORT; } +#endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */ YYDPRINTF ((stderr, "Entering state %d\n", yystate)); @@ -1202,11 +1207,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); goto yybackup; + /*-----------. | yybackup. | `-----------*/ yybackup: - /* Do appropriate processing given the current state. Read a lookahead token if we need one and don't already have one. */ @@ -1279,7 +1284,7 @@ yydefault: /*-----------------------------. -| yyreduce -- Do a reduction. | +| yyreduce -- do a reduction. | `-----------------------------*/ yyreduce: /* yyn is the number of a rule to reduce with. */ @@ -1300,192 +1305,192 @@ yyreduce: switch (yyn) { case 2: -#line 99 "cmCommandArgumentParser.y" /* yacc.c:1646 */ +#line 99 "cmCommandArgumentParser.y" /* yacc.c:1652 */ { (yyval.str) = 0; yyGetParser->SetResult((yyvsp[0].str)); } -#line 1309 "cmCommandArgumentParser.cxx" /* yacc.c:1646 */ +#line 1314 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */ break; case 3: -#line 105 "cmCommandArgumentParser.y" /* yacc.c:1646 */ +#line 105 "cmCommandArgumentParser.y" /* yacc.c:1652 */ { (yyval.str) = (yyvsp[0].str); } -#line 1317 "cmCommandArgumentParser.cxx" /* yacc.c:1646 */ +#line 1322 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */ break; case 4: -#line 108 "cmCommandArgumentParser.y" /* yacc.c:1646 */ +#line 108 "cmCommandArgumentParser.y" /* yacc.c:1652 */ { (yyval.str) = yyGetParser->CombineUnions((yyvsp[-1].str), (yyvsp[0].str)); } -#line 1325 "cmCommandArgumentParser.cxx" /* yacc.c:1646 */ +#line 1330 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */ break; case 5: -#line 113 "cmCommandArgumentParser.y" /* yacc.c:1646 */ +#line 113 "cmCommandArgumentParser.y" /* yacc.c:1652 */ { (yyval.str) = 0; } -#line 1333 "cmCommandArgumentParser.cxx" /* yacc.c:1646 */ +#line 1338 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */ break; case 6: -#line 116 "cmCommandArgumentParser.y" /* yacc.c:1646 */ +#line 116 "cmCommandArgumentParser.y" /* yacc.c:1652 */ { (yyval.str) = yyGetParser->CombineUnions((yyvsp[-1].str), (yyvsp[0].str)); } -#line 1341 "cmCommandArgumentParser.cxx" /* yacc.c:1646 */ +#line 1346 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */ break; case 7: -#line 121 "cmCommandArgumentParser.y" /* yacc.c:1646 */ +#line 121 "cmCommandArgumentParser.y" /* yacc.c:1652 */ { (yyval.str) = (yyvsp[0].str); } -#line 1349 "cmCommandArgumentParser.cxx" /* yacc.c:1646 */ +#line 1354 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */ break; case 8: -#line 124 "cmCommandArgumentParser.y" /* yacc.c:1646 */ +#line 124 "cmCommandArgumentParser.y" /* yacc.c:1652 */ { (yyval.str) = (yyvsp[0].str); } -#line 1357 "cmCommandArgumentParser.cxx" /* yacc.c:1646 */ +#line 1362 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */ break; case 9: -#line 129 "cmCommandArgumentParser.y" /* yacc.c:1646 */ +#line 129 "cmCommandArgumentParser.y" /* yacc.c:1652 */ { (yyval.str) = (yyvsp[0].str); } -#line 1365 "cmCommandArgumentParser.cxx" /* yacc.c:1646 */ +#line 1370 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */ break; case 10: -#line 132 "cmCommandArgumentParser.y" /* yacc.c:1646 */ +#line 132 "cmCommandArgumentParser.y" /* yacc.c:1652 */ { (yyval.str) = (yyvsp[0].str); } -#line 1373 "cmCommandArgumentParser.cxx" /* yacc.c:1646 */ +#line 1378 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */ break; case 11: -#line 135 "cmCommandArgumentParser.y" /* yacc.c:1646 */ +#line 135 "cmCommandArgumentParser.y" /* yacc.c:1652 */ { (yyval.str) = (yyvsp[0].str); } -#line 1381 "cmCommandArgumentParser.cxx" /* yacc.c:1646 */ +#line 1386 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */ break; case 12: -#line 138 "cmCommandArgumentParser.y" /* yacc.c:1646 */ +#line 138 "cmCommandArgumentParser.y" /* yacc.c:1652 */ { (yyval.str) = (yyvsp[0].str); } -#line 1389 "cmCommandArgumentParser.cxx" /* yacc.c:1646 */ +#line 1394 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */ break; case 13: -#line 141 "cmCommandArgumentParser.y" /* yacc.c:1646 */ +#line 141 "cmCommandArgumentParser.y" /* yacc.c:1652 */ { (yyval.str) = (yyvsp[0].str); } -#line 1397 "cmCommandArgumentParser.cxx" /* yacc.c:1646 */ +#line 1402 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */ break; case 14: -#line 144 "cmCommandArgumentParser.y" /* yacc.c:1646 */ +#line 144 "cmCommandArgumentParser.y" /* yacc.c:1652 */ { (yyval.str) = (yyvsp[0].str); } -#line 1405 "cmCommandArgumentParser.cxx" /* yacc.c:1646 */ +#line 1410 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */ break; case 15: -#line 149 "cmCommandArgumentParser.y" /* yacc.c:1646 */ +#line 149 "cmCommandArgumentParser.y" /* yacc.c:1652 */ { (yyval.str) = yyGetParser->ExpandSpecialVariable((yyvsp[-2].str), (yyvsp[-1].str)); } -#line 1413 "cmCommandArgumentParser.cxx" /* yacc.c:1646 */ +#line 1418 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */ break; case 16: -#line 152 "cmCommandArgumentParser.y" /* yacc.c:1646 */ +#line 152 "cmCommandArgumentParser.y" /* yacc.c:1652 */ { (yyval.str) = yyGetParser->ExpandSpecialVariable((yyvsp[-2].str), (yyvsp[-1].str)); } -#line 1421 "cmCommandArgumentParser.cxx" /* yacc.c:1646 */ +#line 1426 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */ break; case 17: -#line 155 "cmCommandArgumentParser.y" /* yacc.c:1646 */ +#line 155 "cmCommandArgumentParser.y" /* yacc.c:1652 */ { (yyval.str) = yyGetParser->ExpandVariable((yyvsp[-1].str)); } -#line 1429 "cmCommandArgumentParser.cxx" /* yacc.c:1646 */ +#line 1434 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */ break; case 18: -#line 158 "cmCommandArgumentParser.y" /* yacc.c:1646 */ +#line 158 "cmCommandArgumentParser.y" /* yacc.c:1652 */ { (yyval.str) = yyGetParser->ExpandVariableForAt((yyvsp[0].str)); } -#line 1437 "cmCommandArgumentParser.cxx" /* yacc.c:1646 */ +#line 1442 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */ break; case 19: -#line 163 "cmCommandArgumentParser.y" /* yacc.c:1646 */ +#line 163 "cmCommandArgumentParser.y" /* yacc.c:1652 */ { (yyval.str) = (yyvsp[0].str); } -#line 1445 "cmCommandArgumentParser.cxx" /* yacc.c:1646 */ +#line 1450 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */ break; case 20: -#line 166 "cmCommandArgumentParser.y" /* yacc.c:1646 */ +#line 166 "cmCommandArgumentParser.y" /* yacc.c:1652 */ { (yyval.str) = (yyvsp[-1].str); } -#line 1453 "cmCommandArgumentParser.cxx" /* yacc.c:1646 */ +#line 1458 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */ break; case 21: -#line 171 "cmCommandArgumentParser.y" /* yacc.c:1646 */ +#line 171 "cmCommandArgumentParser.y" /* yacc.c:1652 */ { (yyval.str) = 0; } -#line 1461 "cmCommandArgumentParser.cxx" /* yacc.c:1646 */ +#line 1466 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */ break; case 22: -#line 174 "cmCommandArgumentParser.y" /* yacc.c:1646 */ +#line 174 "cmCommandArgumentParser.y" /* yacc.c:1652 */ { (yyval.str) = yyGetParser->CombineUnions((yyvsp[-1].str), (yyvsp[0].str)); } -#line 1469 "cmCommandArgumentParser.cxx" /* yacc.c:1646 */ +#line 1474 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */ break; case 23: -#line 179 "cmCommandArgumentParser.y" /* yacc.c:1646 */ +#line 179 "cmCommandArgumentParser.y" /* yacc.c:1652 */ { (yyval.str) = (yyvsp[0].str); } -#line 1477 "cmCommandArgumentParser.cxx" /* yacc.c:1646 */ +#line 1482 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */ break; case 24: -#line 182 "cmCommandArgumentParser.y" /* yacc.c:1646 */ +#line 182 "cmCommandArgumentParser.y" /* yacc.c:1652 */ { (yyval.str) = (yyvsp[0].str); } -#line 1485 "cmCommandArgumentParser.cxx" /* yacc.c:1646 */ +#line 1490 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */ break; -#line 1489 "cmCommandArgumentParser.cxx" /* yacc.c:1646 */ +#line 1494 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */ default: break; } /* User semantic actions sometimes alter yychar, and that requires @@ -1510,14 +1515,13 @@ yyreduce: /* Now 'shift' the result of the reduction. Determine what state that goes to, based on the state we popped back to and the rule number reduced by. */ - - yyn = yyr1[yyn]; - - yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; - if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) - yystate = yytable[yystate]; - else - yystate = yydefgoto[yyn - YYNTOKENS]; + { + const int yylhs = yyr1[yyn] - YYNTOKENS; + const int yyi = yypgoto[yylhs] + *yyssp; + yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyssp + ? yytable[yyi] + : yydefgoto[yylhs]); + } goto yynewstate; @@ -1601,12 +1605,10 @@ yyerrlab: | yyerrorlab -- error raised explicitly by YYERROR. | `---------------------------------------------------*/ yyerrorlab: - - /* Pacify compilers like GCC when the user code never invokes - YYERROR and the label yyerrorlab therefore never appears in user - code. */ - if (/*CONSTCOND*/ 0) - goto yyerrorlab; + /* Pacify compilers when the user code never invokes YYERROR and the + label yyerrorlab therefore never appears in user code. */ + if (0) + YYERROR; /* Do not reclaim the symbols of the rule whose action triggered this YYERROR. */ @@ -1669,6 +1671,7 @@ yyacceptlab: yyresult = 0; goto yyreturn; + /*-----------------------------------. | yyabortlab -- YYABORT comes here. | `-----------------------------------*/ @@ -1676,6 +1679,7 @@ yyabortlab: yyresult = 1; goto yyreturn; + #if !defined yyoverflow || YYERROR_VERBOSE /*-------------------------------------------------. | yyexhaustedlab -- memory exhaustion comes here. | @@ -1686,6 +1690,10 @@ yyexhaustedlab: /* Fall through. */ #endif + +/*-----------------------------------------------------. +| yyreturn -- parsing is finished, return the result. | +`-----------------------------------------------------*/ yyreturn: if (yychar != YYEMPTY) { @@ -1715,7 +1723,7 @@ yyreturn: #endif return yyresult; } -#line 187 "cmCommandArgumentParser.y" /* yacc.c:1906 */ +#line 187 "cmCommandArgumentParser.y" /* yacc.c:1918 */ /* End of grammar */ diff --git a/Source/LexerParser/cmCommandArgumentParserTokens.h b/Source/LexerParser/cmCommandArgumentParserTokens.h index 3172182..56c9794 100644 --- a/Source/LexerParser/cmCommandArgumentParserTokens.h +++ b/Source/LexerParser/cmCommandArgumentParserTokens.h @@ -1,8 +1,9 @@ -/* A Bison parser, made by GNU Bison 3.0.4. */ +/* A Bison parser, made by GNU Bison 3.3.2. */ /* Bison interface for Yacc-like parsers in C - Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc. + Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2019 Free Software Foundation, + Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -30,6 +31,9 @@ This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ +/* Undocumented macros, especially those whose name start with YY_, + are private implementation details. Do not rely on them. */ + #ifndef YY_CMCOMMANDARGUMENT_YY_CMCOMMANDARGUMENTPARSERTOKENS_H_INCLUDED # define YY_CMCOMMANDARGUMENT_YY_CMCOMMANDARGUMENTPARSERTOKENS_H_INCLUDED /* Debug traces. */ diff --git a/Source/LexerParser/cmDependsJavaParser.cxx b/Source/LexerParser/cmDependsJavaParser.cxx index e83afa9..6c1fb2c 100644 --- a/Source/LexerParser/cmDependsJavaParser.cxx +++ b/Source/LexerParser/cmDependsJavaParser.cxx @@ -1,8 +1,9 @@ -/* A Bison parser, made by GNU Bison 3.0.4. */ +/* A Bison parser, made by GNU Bison 3.3.2. */ /* Bison implementation for Yacc-like parsers in C - Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc. + Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2019 Free Software Foundation, + Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -40,11 +41,14 @@ define necessary library symbols; they are noted "INFRINGES ON USER NAME SPACE" below. */ +/* Undocumented macros, especially those whose name start with YY_, + are private implementation details. Do not rely on them. */ + /* Identify Bison output. */ #define YYBISON 1 /* Bison version. */ -#define YYBISON_VERSION "3.0.4" +#define YYBISON_VERSION "3.3.2" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" @@ -67,8 +71,8 @@ #define yynerrs cmDependsJava_yynerrs -/* Copy the first part of user declarations. */ -#line 1 "cmDependsJavaParser.y" /* yacc.c:339 */ +/* First part of user prologue. */ +#line 1 "cmDependsJavaParser.y" /* yacc.c:337 */ /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying file Copyright.txt or https://cmake.org/licensing for details. */ @@ -119,13 +123,16 @@ static void cmDependsJava_yyerror(yyscan_t yyscanner, const char* message); # pragma GCC diagnostic ignored "-Wconversion" #endif -#line 123 "cmDependsJavaParser.cxx" /* yacc.c:339 */ - +#line 127 "cmDependsJavaParser.cxx" /* yacc.c:337 */ # ifndef YY_NULLPTR -# if defined __cplusplus && 201103L <= __cplusplus -# define YY_NULLPTR nullptr +# if defined __cplusplus +# if 201103L <= __cplusplus +# define YY_NULLPTR nullptr +# else +# define YY_NULLPTR 0 +# endif # else -# define YY_NULLPTR 0 +# define YY_NULLPTR ((void*)0) # endif # endif @@ -372,9 +379,7 @@ int cmDependsJava_yyparse (yyscan_t yyscanner); #endif /* !YY_CMDEPENDSJAVA_YY_CMDEPENDSJAVAPARSERTOKENS_H_INCLUDED */ -/* Copy the second part of user declarations. */ -#line 378 "cmDependsJavaParser.cxx" /* yacc.c:358 */ #ifdef short # undef short @@ -395,13 +400,13 @@ typedef signed char yytype_int8; #ifdef YYTYPE_UINT16 typedef YYTYPE_UINT16 yytype_uint16; #else -typedef unsigned short int yytype_uint16; +typedef unsigned short yytype_uint16; #endif #ifdef YYTYPE_INT16 typedef YYTYPE_INT16 yytype_int16; #else -typedef short int yytype_int16; +typedef short yytype_int16; #endif #ifndef YYSIZE_T @@ -413,7 +418,7 @@ typedef short int yytype_int16; # include <stddef.h> /* INFRINGES ON USER NAME SPACE */ # define YYSIZE_T size_t # else -# define YYSIZE_T unsigned int +# define YYSIZE_T unsigned # endif #endif @@ -449,15 +454,6 @@ typedef short int yytype_int16; # define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__)) #endif -#if !defined _Noreturn \ - && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112) -# if defined _MSC_VER && 1200 <= _MSC_VER -# define _Noreturn __declspec (noreturn) -# else -# define _Noreturn YY_ATTRIBUTE ((__noreturn__)) -# endif -#endif - /* Suppress unused-variable warnings by "using" E. */ #if ! defined lint || defined __GNUC__ # define YYUSE(E) ((void) (E)) @@ -465,7 +461,7 @@ typedef short int yytype_int16; # define YYUSE(E) /* empty */ #endif -#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ +#if defined __GNUC__ && ! defined __ICC && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ /* Suppress an incorrect diagnostic about yylval being uninitialized. */ # define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ _Pragma ("GCC diagnostic push") \ @@ -627,16 +623,16 @@ union yyalloc /* YYNSTATES -- Number of states. */ #define YYNSTATES 575 -/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned - by yylex, with out-of-bounds checking. */ #define YYUNDEFTOK 2 #define YYMAXUTOK 360 +/* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM + as returned by yylex, with out-of-bounds checking. */ #define YYTRANSLATE(YYX) \ - ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + ((unsigned) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) /* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM - as returned by yylex, without out-of-bounds checking. */ + as returned by yylex. */ static const yytype_uint8 yytranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -1618,22 +1614,22 @@ static const yytype_uint8 yyr2[] = #define YYRECOVERING() (!!yyerrstatus) -#define YYBACKUP(Token, Value) \ -do \ - if (yychar == YYEMPTY) \ - { \ - yychar = (Token); \ - yylval = (Value); \ - YYPOPSTACK (yylen); \ - yystate = *yyssp; \ - goto yybackup; \ - } \ - else \ - { \ - yyerror (yyscanner, YY_("syntax error: cannot back up")); \ - YYERROR; \ - } \ -while (0) +#define YYBACKUP(Token, Value) \ + do \ + if (yychar == YYEMPTY) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + YYPOPSTACK (yylen); \ + yystate = *yyssp; \ + goto yybackup; \ + } \ + else \ + { \ + yyerror (yyscanner, YY_("syntax error: cannot back up")); \ + YYERROR; \ + } \ + while (0) /* Error token number */ #define YYTERROR 1 @@ -1673,38 +1669,38 @@ do { \ } while (0) -/*----------------------------------------. -| Print this symbol's value on YYOUTPUT. | -`----------------------------------------*/ +/*-----------------------------------. +| Print this symbol's value on YYO. | +`-----------------------------------*/ static void -yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, yyscan_t yyscanner) +yy_symbol_value_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep, yyscan_t yyscanner) { - FILE *yyo = yyoutput; - YYUSE (yyo); + FILE *yyoutput = yyo; + YYUSE (yyoutput); YYUSE (yyscanner); if (!yyvaluep) return; # ifdef YYPRINT if (yytype < YYNTOKENS) - YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); + YYPRINT (yyo, yytoknum[yytype], *yyvaluep); # endif YYUSE (yytype); } -/*--------------------------------. -| Print this symbol on YYOUTPUT. | -`--------------------------------*/ +/*---------------------------. +| Print this symbol on YYO. | +`---------------------------*/ static void -yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, yyscan_t yyscanner) +yy_symbol_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep, yyscan_t yyscanner) { - YYFPRINTF (yyoutput, "%s %s (", + YYFPRINTF (yyo, "%s %s (", yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]); - yy_symbol_value_print (yyoutput, yytype, yyvaluep, yyscanner); - YYFPRINTF (yyoutput, ")"); + yy_symbol_value_print (yyo, yytype, yyvaluep, yyscanner); + YYFPRINTF (yyo, ")"); } /*------------------------------------------------------------------. @@ -1738,7 +1734,7 @@ do { \ static void yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule, yyscan_t yyscanner) { - unsigned long int yylno = yyrline[yyrule]; + unsigned long yylno = yyrline[yyrule]; int yynrhs = yyr2[yyrule]; int yyi; YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", @@ -1749,7 +1745,7 @@ yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule, yyscan_t yysca YYFPRINTF (stderr, " $%d = ", yyi + 1); yy_symbol_print (stderr, yystos[yyssp[yyi + 1 - yynrhs]], - &(yyvsp[(yyi + 1) - (yynrhs)]) + &yyvsp[(yyi + 1) - (yynrhs)] , yyscanner); YYFPRINTF (stderr, "\n"); } @@ -1853,7 +1849,10 @@ yytnamerr (char *yyres, const char *yystr) case '\\': if (*++yyp != '\\') goto do_not_strip_quotes; - /* Fall through. */ + else + goto append; + + append: default: if (yyres) yyres[yyn] = *yyp; @@ -1871,7 +1870,7 @@ yytnamerr (char *yyres, const char *yystr) if (! yyres) return yystrlen (yystr); - return yystpcpy (yyres, yystr) - yyres; + return (YYSIZE_T) (yystpcpy (yyres, yystr) - yyres); } # endif @@ -1949,10 +1948,10 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, yyarg[yycount++] = yytname[yyx]; { YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]); - if (! (yysize <= yysize1 - && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) + if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM) + yysize = yysize1; + else return 2; - yysize = yysize1; } } } @@ -1964,6 +1963,7 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, case N: \ yyformat = S; \ break + default: /* Avoid compiler warnings. */ YYCASE_(0, YY_("syntax error")); YYCASE_(1, YY_("syntax error, unexpected %s")); YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); @@ -1975,9 +1975,10 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, { YYSIZE_T yysize1 = yysize + yystrlen (yyformat); - if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) + if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM) + yysize = yysize1; + else return 2; - yysize = yysize1; } if (*yymsg_alloc < yysize) @@ -2108,23 +2109,31 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); yychar = YYEMPTY; /* Cause a token to be read. */ goto yysetstate; + /*------------------------------------------------------------. -| yynewstate -- Push a new state, which is found in yystate. | +| yynewstate -- push a new state, which is found in yystate. | `------------------------------------------------------------*/ - yynewstate: +yynewstate: /* In all cases, when you get here, the value and location stacks have just been pushed. So pushing a state here evens the stacks. */ yyssp++; - yysetstate: - *yyssp = yystate; + +/*--------------------------------------------------------------------. +| yynewstate -- set current state (the top of the stack) to yystate. | +`--------------------------------------------------------------------*/ +yysetstate: + *yyssp = (yytype_int16) yystate; if (yyss + yystacksize - 1 <= yyssp) +#if !defined yyoverflow && !defined YYSTACK_RELOCATE + goto yyexhaustedlab; +#else { /* Get the current used size of the three stacks, in elements. */ - YYSIZE_T yysize = yyssp - yyss + 1; + YYSIZE_T yysize = (YYSIZE_T) (yyssp - yyss + 1); -#ifdef yyoverflow +# if defined yyoverflow { /* Give user a chance to reallocate the stack. Use copies of these so that the &'s don't force the real ones into @@ -2140,14 +2149,10 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); &yyss1, yysize * sizeof (*yyssp), &yyvs1, yysize * sizeof (*yyvsp), &yystacksize); - yyss = yyss1; yyvs = yyvs1; } -#else /* no yyoverflow */ -# ifndef YYSTACK_RELOCATE - goto yyexhaustedlab; -# else +# else /* defined YYSTACK_RELOCATE */ /* Extend the stack our own way. */ if (YYMAXDEPTH <= yystacksize) goto yyexhaustedlab; @@ -2163,22 +2168,22 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); goto yyexhaustedlab; YYSTACK_RELOCATE (yyss_alloc, yyss); YYSTACK_RELOCATE (yyvs_alloc, yyvs); -# undef YYSTACK_RELOCATE +# undef YYSTACK_RELOCATE if (yyss1 != yyssa) YYSTACK_FREE (yyss1); } # endif -#endif /* no yyoverflow */ yyssp = yyss + yysize - 1; yyvsp = yyvs + yysize - 1; YYDPRINTF ((stderr, "Stack size increased to %lu\n", - (unsigned long int) yystacksize)); + (unsigned long) yystacksize)); if (yyss + yystacksize - 1 <= yyssp) YYABORT; } +#endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */ YYDPRINTF ((stderr, "Entering state %d\n", yystate)); @@ -2187,11 +2192,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); goto yybackup; + /*-----------. | yybackup. | `-----------*/ yybackup: - /* Do appropriate processing given the current state. Read a lookahead token if we need one and don't already have one. */ @@ -2264,7 +2269,7 @@ yydefault: /*-----------------------------. -| yyreduce -- Do a reduction. | +| yyreduce -- do a reduction. | `-----------------------------*/ yyreduce: /* yyn is the number of a rule to reduce with. */ @@ -2285,214 +2290,214 @@ yyreduce: switch (yyn) { case 2: -#line 183 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 183 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2296 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 2301 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 3: -#line 192 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 192 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2307 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 2312 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 4: -#line 200 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 200 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2318 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 2323 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 5: -#line 208 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 208 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2329 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 2334 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 6: -#line 216 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 216 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2340 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 2345 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 7: -#line 224 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 224 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2351 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 2356 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 8: -#line 232 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 232 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2362 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 2367 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 9: -#line 241 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 241 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2373 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 2378 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 10: -#line 249 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 249 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2384 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 2389 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 11: -#line 258 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 258 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2395 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 2400 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 12: -#line 266 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 266 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2406 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 2411 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 13: -#line 275 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 275 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(0); } -#line 2414 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 2419 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 14: -#line 280 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 280 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(0); } -#line 2422 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 2427 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 15: -#line 285 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 285 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(0); } -#line 2430 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 2435 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 16: -#line 290 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 290 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(0); } -#line 2438 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 2443 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 17: -#line 295 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 295 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(0); } -#line 2446 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 2451 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 18: -#line 300 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 300 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(0); } -#line 2454 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 2459 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 19: -#line 305 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 305 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(0); } -#line 2462 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 2467 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 20: -#line 310 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 310 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(0); } -#line 2470 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 2475 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 21: -#line 316 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 316 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2481 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 2486 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 22: -#line 324 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 324 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2492 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 2497 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 23: -#line 333 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 333 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpStoreClass((yyvsp[0].str)); @@ -2500,44 +2505,44 @@ yyreduce: (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2504 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 2509 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 24: -#line 343 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 343 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2515 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 2520 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 25: -#line 352 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 352 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2526 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 2531 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 26: -#line 361 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 361 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(2); jpCheckEmpty(2); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2537 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 2542 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 27: -#line 369 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 369 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(2); jpStoreClass((yyvsp[-1].str)); @@ -2545,56 +2550,56 @@ yyreduce: (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2549 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 2554 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 28: -#line 379 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 379 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); (yyval.str) = (yyvsp[0].str); } -#line 2558 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 2563 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 29: -#line 385 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 385 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); (yyval.str) = (yyvsp[0].str); } -#line 2567 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 2572 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 30: -#line 392 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 392 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); (yyval.str) = (yyvsp[0].str); } -#line 2576 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 2581 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 31: -#line 399 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 399 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); (yyval.str) = (yyvsp[0].str); } -#line 2585 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 2590 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 32: -#line 405 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 405 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(2); (yyval.str) = (yyvsp[0].str); } -#line 2594 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 2599 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 33: -#line 412 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 412 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(3); yyGetParser->AddClassFound((yyvsp[-2].str)); @@ -2602,11 +2607,11 @@ yyreduce: yyGetParser->DeallocateParserType(&((yyvsp[-2].str))); (yyval.str) = const_cast<char*>(yyGetParser->GetCurrentCombine()); } -#line 2606 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 2611 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 34: -#line 421 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 421 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(3); jpStoreClass((yyvsp[-2].str)); @@ -2615,11 +2620,11 @@ yyreduce: (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2619 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 2624 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 35: -#line 431 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 431 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(3); jpStoreClass((yyvsp[-2].str)); @@ -2628,118 +2633,118 @@ yyreduce: (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2632 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 2637 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 36: -#line 441 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 441 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(3); jpCheckEmpty(3); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2643 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 2648 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 37: -#line 450 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 450 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2654 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 2659 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 38: -#line 458 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 458 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2665 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 2670 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 39: -#line 467 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 467 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(3); jpCheckEmpty(3); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2676 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 2681 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 40: -#line 475 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 475 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(0); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2686 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 2691 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 41: -#line 482 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 482 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2697 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 2702 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 42: -#line 490 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 490 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(0); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2707 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 2712 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 43: -#line 497 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 497 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(2); jpCheckEmpty(2); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2718 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 2723 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 44: -#line 505 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 505 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(0); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2728 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 2733 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 45: -#line 512 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 512 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(2); jpCheckEmpty(2); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2739 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 2744 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 46: -#line 521 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 521 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(3); yyGetParser->SetCurrentPackage((yyvsp[-1].str)); @@ -2749,33 +2754,33 @@ yyreduce: (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2753 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 2758 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 47: -#line 533 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 533 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2764 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 2769 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 48: -#line 541 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 541 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2775 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 2780 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 49: -#line 550 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 550 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(3); yyGetParser->AddPackagesImport((yyvsp[-1].str)); @@ -2785,11 +2790,11 @@ yyreduce: (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2789 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 2794 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 50: -#line 562 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 562 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(5); std::string str = (yyvsp[-3].str); @@ -2800,77 +2805,77 @@ yyreduce: (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2804 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 2809 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 51: -#line 575 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 575 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2815 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 2820 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 52: -#line 583 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 583 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2826 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 2831 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 53: -#line 591 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 591 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2837 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 2842 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 54: -#line 600 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 600 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2848 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 2853 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 55: -#line 608 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 608 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(2); jpCheckEmpty(2); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2859 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 2864 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 67: -#line 623 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 623 "cmDependsJavaParser.y" /* yacc.c:1652 */ { yyGetParser->StartClass((yyvsp[0].str)); jpElementStart(3); yyGetParser->DeallocateParserType(&((yyvsp[0].str))); jpCheckEmpty(3); } -#line 2870 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 2875 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 68: -#line 633 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 633 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(2); jpCheckEmpty(2); @@ -2878,11 +2883,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); yyGetParser->EndClass(); } -#line 2882 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 2887 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 69: -#line 642 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 642 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(3); jpCheckEmpty(2); @@ -2890,11 +2895,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); yyGetParser->EndClass(); } -#line 2894 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 2899 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 70: -#line 651 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 651 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(3); jpCheckEmpty(3); @@ -2902,11 +2907,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); yyGetParser->EndClass(); } -#line 2906 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 2911 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 71: -#line 660 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 660 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(4); jpCheckEmpty(4); @@ -2914,226 +2919,226 @@ yyreduce: yyGetParser->SetCurrentCombine(""); yyGetParser->EndClass(); } -#line 2918 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 2923 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 72: -#line 669 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 669 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(0); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2928 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 2933 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 73: -#line 676 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 676 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2939 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 2944 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 74: -#line 685 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 685 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(2); jpCheckEmpty(2); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2950 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 2955 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 75: -#line 694 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 694 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(2); jpCheckEmpty(2); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2961 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 2966 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 76: -#line 703 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 703 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2972 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 2977 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 77: -#line 711 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 711 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(3); jpCheckEmpty(3); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2983 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 2988 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 78: -#line 720 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 720 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(3); jpCheckEmpty(3); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 2994 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 2999 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 79: -#line 728 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 728 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 3004 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3009 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 80: -#line 735 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 735 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(2); jpCheckEmpty(2); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 3015 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3020 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 81: -#line 744 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 744 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 3026 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3031 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 82: -#line 752 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 752 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 3037 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3042 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 83: -#line 760 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 760 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 3048 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3053 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 84: -#line 768 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 768 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 3059 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3064 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 85: -#line 777 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 777 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 3070 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3075 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 86: -#line 785 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 785 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 3081 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3086 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 87: -#line 794 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 794 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(4); } -#line 3089 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3094 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 88: -#line 800 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 800 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 3100 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3105 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 89: -#line 808 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 808 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(3); jpCheckEmpty(3); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 3111 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3116 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 90: -#line 817 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 817 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 3122 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3127 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 91: -#line 825 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 825 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(3); jpCheckEmpty(3); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 3133 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3138 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 92: -#line 834 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 834 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); yyGetParser->DeallocateParserType(&((yyvsp[0].str))); @@ -3141,77 +3146,77 @@ yyreduce: (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 3145 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3150 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 93: -#line 843 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 843 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 3156 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3161 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 94: -#line 852 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 852 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 3167 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3172 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 95: -#line 860 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 860 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 3178 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3183 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 96: -#line 869 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 869 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(2); jpCheckEmpty(2); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 3189 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3194 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 97: -#line 877 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 877 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(2); jpCheckEmpty(2); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 3200 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3205 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 98: -#line 885 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 885 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(3); jpCheckEmpty(3); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 3211 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3216 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 99: -#line 894 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 894 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(4); jpCheckEmpty(4); @@ -3219,11 +3224,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3223 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3228 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 100: -#line 903 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 903 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(4); jpCheckEmpty(4); @@ -3231,22 +3236,22 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3235 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3240 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 101: -#line 912 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 912 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(0); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 3246 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3251 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 102: -#line 920 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 920 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -3254,11 +3259,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3258 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3263 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 103: -#line 930 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 930 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(4); yyGetParser->DeallocateParserType(&((yyvsp[-3].str))); @@ -3267,40 +3272,40 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3271 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3276 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 104: -#line 940 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 940 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(3); } -#line 3280 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3285 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 105: -#line 946 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 946 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(0); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 3291 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3296 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 107: -#line 957 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 957 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); } -#line 3300 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3305 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 108: -#line 963 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 963 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(3); jpCheckEmpty(3); @@ -3308,11 +3313,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3312 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3317 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 109: -#line 973 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 973 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(3); jpCheckEmpty(3); @@ -3320,11 +3325,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3324 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3329 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 110: -#line 983 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 983 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(2); jpCheckEmpty(2); @@ -3332,20 +3337,20 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3336 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3341 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 111: -#line 993 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 993 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); } -#line 3345 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3350 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 112: -#line 999 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 999 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(3); jpCheckEmpty(3); @@ -3353,11 +3358,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3357 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3362 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 113: -#line 1009 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1009 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -3365,11 +3370,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3369 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3374 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 114: -#line 1019 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1019 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(2); jpCheckEmpty(2); @@ -3377,11 +3382,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3381 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3386 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 115: -#line 1029 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1029 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(4); jpCheckEmpty(4); @@ -3389,11 +3394,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3393 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3398 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 116: -#line 1038 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1038 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(5); jpCheckEmpty(5); @@ -3401,11 +3406,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3405 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3410 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 117: -#line 1048 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1048 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(4); yyGetParser->DeallocateParserType(&((yyvsp[-3].str))); @@ -3414,11 +3419,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3418 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3423 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 118: -#line 1059 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1059 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(4); jpCheckEmpty(4); @@ -3426,22 +3431,22 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3430 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3435 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 119: -#line 1068 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1068 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(0); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 3441 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3446 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 120: -#line 1076 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1076 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(2); jpCheckEmpty(2); @@ -3449,11 +3454,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3453 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3458 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 121: -#line 1086 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1086 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(5); jpCheckEmpty(5); @@ -3461,11 +3466,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3465 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3470 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 122: -#line 1095 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1095 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(5); jpCheckEmpty(5); @@ -3473,22 +3478,22 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3477 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3482 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 123: -#line 1105 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1105 "cmDependsJavaParser.y" /* yacc.c:1652 */ { yyGetParser->StartClass((yyvsp[0].str)); jpElementStart(3); yyGetParser->DeallocateParserType(&((yyvsp[0].str))); jpCheckEmpty(3); } -#line 3488 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3493 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 124: -#line 1114 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1114 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(2); jpCheckEmpty(2); @@ -3496,21 +3501,21 @@ yyreduce: yyGetParser->SetCurrentCombine(""); yyGetParser->EndClass(); } -#line 3500 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3505 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 125: -#line 1123 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1123 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(0); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 3510 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3515 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 126: -#line 1130 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1130 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -3518,11 +3523,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3522 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3527 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 127: -#line 1140 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1140 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(2); jpCheckEmpty(2); @@ -3530,11 +3535,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3534 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3539 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 128: -#line 1149 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1149 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(3); jpCheckEmpty(3); @@ -3542,11 +3547,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3546 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3551 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 129: -#line 1159 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1159 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(3); jpCheckEmpty(3); @@ -3554,33 +3559,33 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3558 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3563 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 130: -#line 1168 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1168 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(0); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 3569 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3574 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 131: -#line 1176 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1176 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(2); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 3580 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3585 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 132: -#line 1185 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1185 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -3588,11 +3593,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3592 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3597 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 133: -#line 1194 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1194 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -3600,11 +3605,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3604 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3609 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 134: -#line 1203 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1203 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -3612,22 +3617,22 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3616 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3621 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 135: -#line 1212 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1212 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(2); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 3627 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3632 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 136: -#line 1220 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1220 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -3635,22 +3640,22 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3639 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3644 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 137: -#line 1229 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1229 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(2); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 3650 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3655 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 138: -#line 1238 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1238 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -3658,11 +3663,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3662 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3667 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 139: -#line 1248 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1248 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(2); jpCheckEmpty(2); @@ -3670,11 +3675,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3674 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3679 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 140: -#line 1258 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1258 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -3682,11 +3687,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3686 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3691 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 141: -#line 1267 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1267 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(2); jpCheckEmpty(2); @@ -3694,11 +3699,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3698 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3703 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 142: -#line 1277 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1277 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(3); jpCheckEmpty(3); @@ -3706,22 +3711,22 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3710 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3715 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 143: -#line 1286 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1286 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 3721 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3726 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 144: -#line 1294 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1294 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -3729,11 +3734,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3733 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3738 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 145: -#line 1303 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1303 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(2); jpCheckEmpty(2); @@ -3741,11 +3746,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3745 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3750 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 146: -#line 1313 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1313 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -3753,11 +3758,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3757 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3762 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 147: -#line 1322 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1322 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(3); jpCheckEmpty(3); @@ -3765,33 +3770,33 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3769 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3774 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 148: -#line 1332 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1332 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(4); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 3780 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3785 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 149: -#line 1340 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1340 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 3791 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3796 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 150: -#line 1348 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1348 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -3799,11 +3804,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3803 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3808 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 151: -#line 1358 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1358 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -3811,11 +3816,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3815 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3820 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 152: -#line 1367 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1367 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(2); @@ -3823,11 +3828,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3827 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3832 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 153: -#line 1377 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1377 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -3835,11 +3840,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3839 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3844 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 154: -#line 1386 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1386 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -3847,11 +3852,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3851 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3856 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 155: -#line 1395 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1395 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -3859,11 +3864,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3863 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3868 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 156: -#line 1405 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1405 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(2); @@ -3871,11 +3876,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3875 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3880 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 157: -#line 1415 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1415 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(3); @@ -3883,11 +3888,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3887 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3892 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 158: -#line 1424 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1424 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(2); @@ -3895,11 +3900,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3899 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3904 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 159: -#line 1434 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1434 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -3907,11 +3912,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3911 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3916 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 160: -#line 1443 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1443 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -3919,11 +3924,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3923 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3928 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 161: -#line 1452 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1452 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -3931,11 +3936,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3935 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3940 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 162: -#line 1461 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1461 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -3943,11 +3948,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3947 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3952 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 163: -#line 1470 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1470 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -3955,11 +3960,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3959 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3964 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 164: -#line 1479 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1479 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -3967,11 +3972,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3971 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3976 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 165: -#line 1489 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1489 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -3979,11 +3984,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3983 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 3988 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 166: -#line 1498 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1498 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -3991,11 +3996,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 3995 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4000 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 167: -#line 1507 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1507 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -4003,11 +4008,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4007 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4012 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 168: -#line 1516 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1516 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -4015,11 +4020,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4019 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4024 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 169: -#line 1525 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1525 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -4027,11 +4032,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4031 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4036 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 170: -#line 1535 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1535 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -4039,11 +4044,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4043 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4048 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 171: -#line 1544 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1544 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -4051,11 +4056,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4055 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4060 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 172: -#line 1553 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1553 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -4063,11 +4068,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4067 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4072 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 173: -#line 1562 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1562 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -4075,11 +4080,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4079 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4084 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 174: -#line 1571 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1571 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -4087,11 +4092,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4091 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4096 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 175: -#line 1580 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1580 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -4099,11 +4104,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4103 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4108 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 176: -#line 1589 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1589 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -4111,11 +4116,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4115 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4120 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 177: -#line 1598 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1598 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -4123,11 +4128,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4127 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4132 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 178: -#line 1607 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1607 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -4135,11 +4140,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4139 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4144 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 179: -#line 1616 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1616 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -4147,11 +4152,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4151 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4156 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 180: -#line 1625 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1625 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -4159,11 +4164,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4163 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4168 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 181: -#line 1634 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1634 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -4171,11 +4176,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4175 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4180 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 182: -#line 1644 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1644 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -4183,11 +4188,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4187 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4192 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 183: -#line 1654 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1654 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(3); yyGetParser->DeallocateParserType(&((yyvsp[-2].str))); @@ -4196,11 +4201,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4200 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4205 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 184: -#line 1665 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1665 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(3); jpCheckEmpty(3); @@ -4208,11 +4213,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4212 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4217 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 185: -#line 1675 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1675 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(2); jpCheckEmpty(2); @@ -4220,11 +4225,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4224 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4229 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 186: -#line 1685 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1685 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -4232,11 +4237,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4236 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4241 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 187: -#line 1694 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1694 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -4244,11 +4249,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4248 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4253 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 188: -#line 1703 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1703 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -4256,11 +4261,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4260 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4265 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 189: -#line 1712 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1712 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -4268,11 +4273,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4272 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4277 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 190: -#line 1721 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1721 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -4280,11 +4285,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4284 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4289 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 191: -#line 1730 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1730 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -4292,11 +4297,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4296 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4301 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 192: -#line 1739 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1739 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -4304,11 +4309,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4308 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4313 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 193: -#line 1749 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1749 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(5); jpCheckEmpty(5); @@ -4316,11 +4321,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4320 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4325 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 194: -#line 1759 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1759 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(7); jpCheckEmpty(7); @@ -4328,11 +4333,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4332 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4337 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 195: -#line 1769 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1769 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(7); jpCheckEmpty(7); @@ -4340,40 +4345,40 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4344 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4349 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 196: -#line 1779 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1779 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(5); } -#line 4353 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4358 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 197: -#line 1786 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1786 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(4); } -#line 4362 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4367 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 198: -#line 1792 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1792 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(0); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 4373 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4378 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 199: -#line 1800 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1800 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -4381,22 +4386,22 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4385 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4390 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 200: -#line 1809 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1809 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(0); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 4396 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4401 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 201: -#line 1817 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1817 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(2); jpCheckEmpty(2); @@ -4404,11 +4409,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4408 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4413 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 202: -#line 1827 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1827 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(2); jpCheckEmpty(2); @@ -4416,11 +4421,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4420 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4425 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 203: -#line 1837 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1837 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -4428,11 +4433,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4432 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4437 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 204: -#line 1846 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1846 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(2); jpCheckEmpty(2); @@ -4440,11 +4445,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4444 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4449 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 205: -#line 1856 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1856 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(3); jpCheckEmpty(3); @@ -4452,11 +4457,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4456 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4461 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 206: -#line 1865 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1865 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(2); jpCheckEmpty(2); @@ -4464,58 +4469,58 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4468 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4473 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 207: -#line 1875 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1875 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(5); } -#line 4477 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4482 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 208: -#line 1882 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1882 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(5); } -#line 4486 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4491 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 209: -#line 1889 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1889 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(7); } -#line 4495 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4500 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 210: -#line 1897 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1897 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(9); } -#line 4504 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4509 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 211: -#line 1903 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1903 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 4515 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4520 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 212: -#line 1911 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1911 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -4523,22 +4528,22 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4527 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4532 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 213: -#line 1920 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1920 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(0); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 4538 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4543 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 214: -#line 1928 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1928 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -4546,33 +4551,33 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4550 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4555 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 215: -#line 1939 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1939 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(9); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 4561 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4566 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 216: -#line 1947 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1947 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(0); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 4572 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4577 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 217: -#line 1955 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1955 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -4580,11 +4585,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4584 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4589 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 218: -#line 1965 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1965 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -4592,11 +4597,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4596 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4601 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 219: -#line 1974 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1974 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -4604,11 +4609,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4608 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4613 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 220: -#line 1984 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1984 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -4616,11 +4621,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4620 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4625 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 221: -#line 1994 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 1994 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -4628,11 +4633,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4632 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4637 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 222: -#line 2003 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2003 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(3); jpCheckEmpty(3); @@ -4640,11 +4645,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4644 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4649 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 223: -#line 2013 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2013 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(3); jpCheckEmpty(3); @@ -4652,11 +4657,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4656 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4661 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 224: -#line 2022 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2022 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(5); jpCheckEmpty(5); @@ -4664,11 +4669,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4668 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4673 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 225: -#line 2032 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2032 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(3); yyGetParser->DeallocateParserType(&((yyvsp[-1].str))); @@ -4677,31 +4682,31 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4681 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4686 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 226: -#line 2042 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2042 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(0); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 4692 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4697 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 227: -#line 2050 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2050 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); } -#line 4701 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4706 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 228: -#line 2057 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2057 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(3); yyGetParser->DeallocateParserType(&((yyvsp[-1].str))); @@ -4710,11 +4715,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4714 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4719 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 229: -#line 2068 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2068 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(3); jpCheckEmpty(3); @@ -4722,11 +4727,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4726 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4731 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 230: -#line 2078 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2078 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(3); jpCheckEmpty(3); @@ -4734,11 +4739,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4738 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4743 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 231: -#line 2088 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2088 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(5); jpCheckEmpty(5); @@ -4746,11 +4751,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4750 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4755 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 232: -#line 2098 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2098 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(3); jpCheckEmpty(3); @@ -4758,11 +4763,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4762 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4767 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 233: -#line 2107 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2107 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(4); jpCheckEmpty(4); @@ -4770,22 +4775,22 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4774 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4779 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 234: -#line 2116 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2116 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 4785 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4790 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 235: -#line 2124 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2124 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -4793,11 +4798,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4797 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4802 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 236: -#line 2134 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2134 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -4805,11 +4810,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4809 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4814 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 237: -#line 2143 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2143 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(2); jpCheckEmpty(2); @@ -4817,20 +4822,20 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4821 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4826 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 238: -#line 2153 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2153 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(5); } -#line 4830 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4835 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 239: -#line 2160 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2160 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(2); jpCheckEmpty(2); @@ -4838,11 +4843,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4842 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4847 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 240: -#line 2170 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2170 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -4850,11 +4855,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4854 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4859 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 241: -#line 2179 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2179 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -4862,11 +4867,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4866 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4871 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 242: -#line 2189 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2189 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -4874,20 +4879,20 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4878 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4883 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 243: -#line 2198 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2198 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); } -#line 4887 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4892 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 244: -#line 2204 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2204 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(3); jpCheckEmpty(3); @@ -4895,11 +4900,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4899 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4904 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 245: -#line 2213 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2213 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -4907,11 +4912,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4911 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4916 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 246: -#line 2222 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2222 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -4919,11 +4924,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4923 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4928 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 247: -#line 2231 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2231 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -4931,11 +4936,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4935 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4940 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 248: -#line 2240 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2240 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -4943,11 +4948,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4947 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4952 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 249: -#line 2250 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2250 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(6); jpCheckEmpty(6); @@ -4955,22 +4960,22 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4959 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4964 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 250: -#line 2259 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2259 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(0); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 4970 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4975 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 251: -#line 2267 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2267 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -4978,22 +4983,22 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 4982 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4987 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 252: -#line 2276 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2276 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(0); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 4993 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 4998 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 253: -#line 2284 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2284 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -5001,11 +5006,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5005 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5010 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 254: -#line 2294 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2294 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -5013,11 +5018,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5017 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5022 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 255: -#line 2303 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2303 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(3); jpCheckEmpty(3); @@ -5025,11 +5030,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5029 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5034 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 256: -#line 2313 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2313 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(4); jpCheckEmpty(4); @@ -5037,11 +5042,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5041 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5046 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 257: -#line 2322 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2322 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(4); jpCheckEmpty(4); @@ -5049,11 +5054,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5053 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5058 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 258: -#line 2331 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2331 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(4); jpCheckEmpty(4); @@ -5061,11 +5066,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5065 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5070 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 259: -#line 2340 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2340 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(4); jpCheckEmpty(4); @@ -5073,22 +5078,22 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5077 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5082 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 260: -#line 2349 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2349 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(0); (yyval.str) = 0; yyGetParser->SetCurrentCombine(""); } -#line 5088 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5093 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 261: -#line 2357 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2357 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -5096,11 +5101,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5100 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5105 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 262: -#line 2367 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2367 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -5108,11 +5113,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5112 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5117 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 263: -#line 2376 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2376 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(2); jpCheckEmpty(2); @@ -5120,11 +5125,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5124 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5129 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 264: -#line 2386 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2386 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(3); jpCheckEmpty(3); @@ -5132,29 +5137,29 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5136 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5141 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 265: -#line 2396 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2396 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(2); } -#line 5145 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5150 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 266: -#line 2402 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2402 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(3); } -#line 5154 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5159 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 267: -#line 2409 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2409 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(3); yyGetParser->DeallocateParserType(&((yyvsp[0].str))); @@ -5163,11 +5168,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5167 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5172 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 268: -#line 2419 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2419 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(3); yyGetParser->DeallocateParserType(&((yyvsp[0].str))); @@ -5176,11 +5181,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5180 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5185 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 269: -#line 2429 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2429 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(3); yyGetParser->DeallocateParserType(&((yyvsp[0].str))); @@ -5189,11 +5194,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5193 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5198 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 270: -#line 2439 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2439 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(3); yyGetParser->DeallocateParserType(&((yyvsp[0].str))); @@ -5202,11 +5207,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5206 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5211 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 271: -#line 2450 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2450 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(4); yyGetParser->DeallocateParserType(&((yyvsp[-3].str))); @@ -5215,11 +5220,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5219 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5224 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 272: -#line 2460 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2460 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(6); yyGetParser->DeallocateParserType(&((yyvsp[-5].str))); @@ -5229,11 +5234,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5233 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5238 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 273: -#line 2471 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2471 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(6); yyGetParser->DeallocateParserType(&((yyvsp[-3].str))); @@ -5242,11 +5247,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5246 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5251 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 274: -#line 2481 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2481 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(6); yyGetParser->DeallocateParserType(&((yyvsp[-3].str))); @@ -5255,11 +5260,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5259 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5264 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 275: -#line 2492 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2492 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(4); yyGetParser->DeallocateParserType(&((yyvsp[-3].str))); @@ -5268,11 +5273,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5272 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5277 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 276: -#line 2502 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2502 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(4); jpCheckEmpty(4); @@ -5280,11 +5285,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5284 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5289 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 277: -#line 2512 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2512 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -5292,11 +5297,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5296 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5301 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 278: -#line 2521 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2521 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); yyGetParser->DeallocateParserType(&((yyvsp[0].str))); @@ -5304,11 +5309,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5308 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5313 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 279: -#line 2530 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2530 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(3); jpCheckEmpty(3); @@ -5316,11 +5321,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5320 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5325 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 280: -#line 2539 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2539 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -5328,11 +5333,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5332 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5337 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 281: -#line 2548 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2548 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -5340,11 +5345,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5344 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5349 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 282: -#line 2558 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2558 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(2); jpCheckEmpty(2); @@ -5352,11 +5357,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5356 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5361 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 283: -#line 2568 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2568 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(2); jpCheckEmpty(2); @@ -5364,11 +5369,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5368 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5373 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 284: -#line 2578 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2578 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -5376,11 +5381,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5380 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5385 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 285: -#line 2587 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2587 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -5388,11 +5393,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5392 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5397 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 286: -#line 2596 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2596 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(2); jpCheckEmpty(2); @@ -5400,11 +5405,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5404 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5409 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 287: -#line 2605 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2605 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(2); jpCheckEmpty(2); @@ -5412,11 +5417,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5416 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5421 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 288: -#line 2614 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2614 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -5424,11 +5429,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5428 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5433 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 289: -#line 2624 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2624 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(2); jpCheckEmpty(2); @@ -5436,11 +5441,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5440 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5445 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 290: -#line 2634 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2634 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(2); jpCheckEmpty(2); @@ -5448,11 +5453,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5452 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5457 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 291: -#line 2644 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2644 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -5460,11 +5465,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5464 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5469 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 292: -#line 2653 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2653 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(2); jpCheckEmpty(2); @@ -5472,11 +5477,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5476 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5481 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 293: -#line 2662 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2662 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(2); jpCheckEmpty(2); @@ -5484,11 +5489,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5488 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5493 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 294: -#line 2671 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2671 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -5496,11 +5501,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5500 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5505 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 295: -#line 2681 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2681 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(5); jpCheckEmpty(5); @@ -5508,11 +5513,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5512 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5517 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 296: -#line 2690 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2690 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(4); jpCheckEmpty(4); @@ -5520,20 +5525,20 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5524 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5529 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 297: -#line 2699 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2699 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(5); } -#line 5533 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5538 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 298: -#line 2706 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2706 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -5541,11 +5546,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5545 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5550 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 299: -#line 2715 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2715 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(3); jpCheckEmpty(3); @@ -5553,11 +5558,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5557 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5562 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 300: -#line 2724 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2724 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(3); jpCheckEmpty(3); @@ -5565,11 +5570,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5569 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5574 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 301: -#line 2733 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2733 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(3); jpCheckEmpty(3); @@ -5577,11 +5582,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5581 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5586 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 302: -#line 2743 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2743 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -5589,11 +5594,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5593 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5598 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 303: -#line 2752 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2752 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(3); jpCheckEmpty(3); @@ -5601,11 +5606,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5605 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5610 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 304: -#line 2761 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2761 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(3); jpCheckEmpty(3); @@ -5613,11 +5618,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5617 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5622 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 305: -#line 2771 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2771 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -5625,11 +5630,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5629 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5634 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 306: -#line 2780 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2780 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(3); jpCheckEmpty(3); @@ -5637,11 +5642,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5641 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5646 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 307: -#line 2789 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2789 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(3); jpCheckEmpty(3); @@ -5649,11 +5654,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5653 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5658 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 308: -#line 2798 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2798 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(3); jpCheckEmpty(3); @@ -5661,11 +5666,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5665 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5670 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 309: -#line 2808 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2808 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -5673,11 +5678,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5677 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5682 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 310: -#line 2817 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2817 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(3); jpCheckEmpty(3); @@ -5685,11 +5690,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5689 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5694 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 311: -#line 2826 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2826 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(3); jpCheckEmpty(3); @@ -5697,11 +5702,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5701 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5706 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 312: -#line 2835 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2835 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(3); jpCheckEmpty(3); @@ -5709,11 +5714,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5713 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5718 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 313: -#line 2844 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2844 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(3); jpCheckEmpty(3); @@ -5721,11 +5726,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5725 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5730 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 314: -#line 2853 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2853 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(3); jpCheckEmpty(3); @@ -5733,11 +5738,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5737 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5742 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 315: -#line 2863 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2863 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -5745,11 +5750,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5749 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5754 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 316: -#line 2872 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2872 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(3); jpCheckEmpty(3); @@ -5757,11 +5762,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5761 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5766 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 317: -#line 2881 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2881 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(3); jpCheckEmpty(3); @@ -5769,11 +5774,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5773 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5778 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 318: -#line 2891 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2891 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -5781,11 +5786,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5785 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5790 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 319: -#line 2900 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2900 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(3); jpCheckEmpty(3); @@ -5793,11 +5798,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5797 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5802 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 320: -#line 2910 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2910 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -5805,11 +5810,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5809 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5814 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 321: -#line 2919 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2919 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(3); jpCheckEmpty(3); @@ -5817,11 +5822,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5821 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5826 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 322: -#line 2929 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2929 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -5829,11 +5834,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5833 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5838 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 323: -#line 2938 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2938 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(3); jpCheckEmpty(3); @@ -5841,11 +5846,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5845 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5850 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 324: -#line 2948 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2948 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -5853,11 +5858,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5857 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5862 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 325: -#line 2957 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2957 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(3); jpCheckEmpty(3); @@ -5865,11 +5870,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5869 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5874 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 326: -#line 2967 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2967 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -5877,11 +5882,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5881 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5886 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 327: -#line 2976 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2976 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(3); jpCheckEmpty(3); @@ -5889,11 +5894,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5893 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5898 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 328: -#line 2986 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2986 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -5901,11 +5906,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5905 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5910 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 329: -#line 2995 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 2995 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(5); jpCheckEmpty(5); @@ -5913,11 +5918,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5917 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5922 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 330: -#line 3005 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 3005 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -5925,11 +5930,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5929 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5934 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 331: -#line 3014 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 3014 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -5937,11 +5942,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5941 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5946 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 332: -#line 3024 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 3024 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(3); jpCheckEmpty(3); @@ -5949,11 +5954,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5953 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5958 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 333: -#line 3034 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 3034 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); yyGetParser->DeallocateParserType(&((yyvsp[0].str))); @@ -5962,11 +5967,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5966 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5971 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 334: -#line 3044 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 3044 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -5974,11 +5979,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5978 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5983 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 335: -#line 3053 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 3053 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -5986,11 +5991,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 5990 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 5995 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 336: -#line 3063 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 3063 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -5998,11 +6003,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 6002 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 6007 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 337: -#line 3072 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 3072 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -6010,11 +6015,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 6014 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 6019 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 338: -#line 3081 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 3081 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -6022,11 +6027,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 6026 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 6031 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 339: -#line 3090 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 3090 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -6034,11 +6039,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 6038 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 6043 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 340: -#line 3099 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 3099 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -6046,11 +6051,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 6050 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 6055 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 341: -#line 3108 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 3108 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -6058,11 +6063,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 6062 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 6067 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 342: -#line 3117 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 3117 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -6070,11 +6075,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 6074 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 6079 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 343: -#line 3126 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 3126 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -6082,11 +6087,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 6086 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 6091 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 344: -#line 3135 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 3135 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -6094,11 +6099,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 6098 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 6103 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 345: -#line 3144 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 3144 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -6106,11 +6111,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 6110 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 6115 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 346: -#line 3153 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 3153 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -6118,11 +6123,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 6122 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 6127 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 347: -#line 3162 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 3162 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -6130,11 +6135,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 6134 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 6139 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 348: -#line 3172 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 3172 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -6142,11 +6147,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 6146 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 6151 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 349: -#line 3182 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 3182 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -6154,11 +6159,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 6158 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 6163 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 350: -#line 3192 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 3192 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(1); jpCheckEmpty(1); @@ -6166,11 +6171,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 6170 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 6175 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; case 351: -#line 3201 "cmDependsJavaParser.y" /* yacc.c:1646 */ +#line 3201 "cmDependsJavaParser.y" /* yacc.c:1652 */ { jpElementStart(3); jpStoreClass((yyvsp[-2].str)); @@ -6179,11 +6184,11 @@ yyreduce: yyGetParser->SetCurrentCombine(""); } -#line 6183 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 6188 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ break; -#line 6187 "cmDependsJavaParser.cxx" /* yacc.c:1646 */ +#line 6192 "cmDependsJavaParser.cxx" /* yacc.c:1652 */ default: break; } /* User semantic actions sometimes alter yychar, and that requires @@ -6208,14 +6213,13 @@ yyreduce: /* Now 'shift' the result of the reduction. Determine what state that goes to, based on the state we popped back to and the rule number reduced by. */ - - yyn = yyr1[yyn]; - - yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; - if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) - yystate = yytable[yystate]; - else - yystate = yydefgoto[yyn - YYNTOKENS]; + { + const int yylhs = yyr1[yyn] - YYNTOKENS; + const int yyi = yypgoto[yylhs] + *yyssp; + yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyssp + ? yytable[yyi] + : yydefgoto[yylhs]); + } goto yynewstate; @@ -6299,12 +6303,10 @@ yyerrlab: | yyerrorlab -- error raised explicitly by YYERROR. | `---------------------------------------------------*/ yyerrorlab: - - /* Pacify compilers like GCC when the user code never invokes - YYERROR and the label yyerrorlab therefore never appears in user - code. */ - if (/*CONSTCOND*/ 0) - goto yyerrorlab; + /* Pacify compilers when the user code never invokes YYERROR and the + label yyerrorlab therefore never appears in user code. */ + if (0) + YYERROR; /* Do not reclaim the symbols of the rule whose action triggered this YYERROR. */ @@ -6367,6 +6369,7 @@ yyacceptlab: yyresult = 0; goto yyreturn; + /*-----------------------------------. | yyabortlab -- YYABORT comes here. | `-----------------------------------*/ @@ -6374,6 +6377,7 @@ yyabortlab: yyresult = 1; goto yyreturn; + #if !defined yyoverflow || YYERROR_VERBOSE /*-------------------------------------------------. | yyexhaustedlab -- memory exhaustion comes here. | @@ -6384,6 +6388,10 @@ yyexhaustedlab: /* Fall through. */ #endif + +/*-----------------------------------------------------. +| yyreturn -- parsing is finished, return the result. | +`-----------------------------------------------------*/ yyreturn: if (yychar != YYEMPTY) { @@ -6413,7 +6421,7 @@ yyreturn: #endif return yyresult; } -#line 3210 "cmDependsJavaParser.y" /* yacc.c:1906 */ +#line 3210 "cmDependsJavaParser.y" /* yacc.c:1918 */ /* End of grammar */ diff --git a/Source/LexerParser/cmDependsJavaParserTokens.h b/Source/LexerParser/cmDependsJavaParserTokens.h index 7f18f1d..6bbc084 100644 --- a/Source/LexerParser/cmDependsJavaParserTokens.h +++ b/Source/LexerParser/cmDependsJavaParserTokens.h @@ -1,8 +1,9 @@ -/* A Bison parser, made by GNU Bison 3.0.4. */ +/* A Bison parser, made by GNU Bison 3.3.2. */ /* Bison interface for Yacc-like parsers in C - Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc. + Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2019 Free Software Foundation, + Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -30,6 +31,9 @@ This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ +/* Undocumented macros, especially those whose name start with YY_, + are private implementation details. Do not rely on them. */ + #ifndef YY_CMDEPENDSJAVA_YY_CMDEPENDSJAVAPARSERTOKENS_H_INCLUDED # define YY_CMDEPENDSJAVA_YY_CMDEPENDSJAVAPARSERTOKENS_H_INCLUDED /* Debug traces. */ diff --git a/Source/LexerParser/cmExprParser.cxx b/Source/LexerParser/cmExprParser.cxx index 73ece2b..8416e72 100644 --- a/Source/LexerParser/cmExprParser.cxx +++ b/Source/LexerParser/cmExprParser.cxx @@ -1,8 +1,9 @@ -/* A Bison parser, made by GNU Bison 3.0.4. */ +/* A Bison parser, made by GNU Bison 3.3.2. */ /* Bison implementation for Yacc-like parsers in C - Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc. + Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2019 Free Software Foundation, + Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -40,11 +41,14 @@ define necessary library symbols; they are noted "INFRINGES ON USER NAME SPACE" below. */ +/* Undocumented macros, especially those whose name start with YY_, + are private implementation details. Do not rely on them. */ + /* Identify Bison output. */ #define YYBISON 1 /* Bison version. */ -#define YYBISON_VERSION "3.0.4" +#define YYBISON_VERSION "3.3.2" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" @@ -67,8 +71,8 @@ #define yynerrs cmExpr_yynerrs -/* Copy the first part of user declarations. */ -#line 1 "cmExprParser.y" /* yacc.c:339 */ +/* First part of user prologue. */ +#line 1 "cmExprParser.y" /* yacc.c:337 */ /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying file Copyright.txt or https://cmake.org/licensing for details. */ @@ -112,13 +116,16 @@ static void cmExpr_yyerror(yyscan_t yyscanner, const char* message); # pragma GCC diagnostic ignored "-Wconversion" #endif -#line 116 "cmExprParser.cxx" /* yacc.c:339 */ - +#line 120 "cmExprParser.cxx" /* yacc.c:337 */ # ifndef YY_NULLPTR -# if defined __cplusplus && 201103L <= __cplusplus -# define YY_NULLPTR nullptr +# if defined __cplusplus +# if 201103L <= __cplusplus +# define YY_NULLPTR nullptr +# else +# define YY_NULLPTR 0 +# endif # else -# define YY_NULLPTR 0 +# define YY_NULLPTR ((void*)0) # endif # endif @@ -187,9 +194,7 @@ int cmExpr_yyparse (yyscan_t yyscanner); #endif /* !YY_CMEXPR_YY_CMEXPRPARSERTOKENS_H_INCLUDED */ -/* Copy the second part of user declarations. */ -#line 193 "cmExprParser.cxx" /* yacc.c:358 */ #ifdef short # undef short @@ -210,13 +215,13 @@ typedef signed char yytype_int8; #ifdef YYTYPE_UINT16 typedef YYTYPE_UINT16 yytype_uint16; #else -typedef unsigned short int yytype_uint16; +typedef unsigned short yytype_uint16; #endif #ifdef YYTYPE_INT16 typedef YYTYPE_INT16 yytype_int16; #else -typedef short int yytype_int16; +typedef short yytype_int16; #endif #ifndef YYSIZE_T @@ -228,7 +233,7 @@ typedef short int yytype_int16; # include <stddef.h> /* INFRINGES ON USER NAME SPACE */ # define YYSIZE_T size_t # else -# define YYSIZE_T unsigned int +# define YYSIZE_T unsigned # endif #endif @@ -264,15 +269,6 @@ typedef short int yytype_int16; # define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__)) #endif -#if !defined _Noreturn \ - && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112) -# if defined _MSC_VER && 1200 <= _MSC_VER -# define _Noreturn __declspec (noreturn) -# else -# define _Noreturn YY_ATTRIBUTE ((__noreturn__)) -# endif -#endif - /* Suppress unused-variable warnings by "using" E. */ #if ! defined lint || defined __GNUC__ # define YYUSE(E) ((void) (E)) @@ -280,7 +276,7 @@ typedef short int yytype_int16; # define YYUSE(E) /* empty */ #endif -#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ +#if defined __GNUC__ && ! defined __ICC && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ /* Suppress an incorrect diagnostic about yylval being uninitialized. */ # define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ _Pragma ("GCC diagnostic push") \ @@ -429,29 +425,29 @@ union yyalloc #endif /* !YYCOPY_NEEDED */ /* YYFINAL -- State number of the termination state. */ -#define YYFINAL 17 +#define YYFINAL 19 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 30 +#define YYLAST 34 /* YYNTOKENS -- Number of terminals. */ #define YYNTOKENS 17 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 10 /* YYNRULES -- Number of rules. */ -#define YYNRULES 23 +#define YYNRULES 24 /* YYNSTATES -- Number of states. */ -#define YYNSTATES 39 +#define YYNSTATES 41 -/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned - by yylex, with out-of-bounds checking. */ #define YYUNDEFTOK 2 #define YYMAXUTOK 271 +/* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM + as returned by yylex, with out-of-bounds checking. */ #define YYTRANSLATE(YYX) \ - ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + ((unsigned) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) /* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM - as returned by yylex, without out-of-bounds checking. */ + as returned by yylex. */ static const yytype_uint8 yytranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -490,7 +486,7 @@ static const yytype_uint8 yyrline[] = { 0, 77, 77, 82, 85, 90, 93, 98, 101, 106, 109, 112, 117, 120, 123, 128, 131, 134, 140, 145, - 148, 151, 156, 159 + 148, 151, 154, 159, 162 }; #endif @@ -517,10 +513,10 @@ static const yytype_uint16 yytoknum[] = }; # endif -#define YYPACT_NINF -8 +#define YYPACT_NINF -11 #define yypact_value_is_default(Yystate) \ - (!!((Yystate) == (-8))) + (!!((Yystate) == (-11))) #define YYTABLE_NINF -1 @@ -531,10 +527,11 @@ static const yytype_uint16 yytoknum[] = STATE-NUM. */ static const yytype_int8 yypact[] = { - 0, 0, 0, 0, -8, 2, -7, -5, 8, 3, - 10, 1, -8, -8, -8, -8, 6, -8, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -8, -5, - 8, 3, 10, 10, 1, 1, -8, -8, -8 + 1, 1, 1, 1, 1, -11, 6, -10, -4, 9, + 4, 11, 2, -11, -11, -11, -11, 7, -11, -11, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + -11, -4, 9, 4, 11, 11, 2, 2, -11, -11, + -11 }; /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. @@ -542,22 +539,23 @@ static const yytype_int8 yypact[] = means the default is an error. */ static const yytype_uint8 yydefact[] = { - 0, 0, 0, 0, 22, 0, 2, 3, 5, 7, - 9, 12, 15, 19, 20, 21, 0, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 23, 4, - 6, 8, 10, 11, 13, 14, 16, 17, 18 + 0, 0, 0, 0, 0, 23, 0, 2, 3, 5, + 7, 9, 12, 15, 19, 20, 21, 0, 22, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 24, 4, 6, 8, 10, 11, 13, 14, 16, 17, + 18 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int8 yypgoto[] = { - -8, -8, 12, 5, 11, 9, -2, 4, -1, -8 + -11, -11, 22, 10, 8, 12, -3, -2, -1, -11 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int8 yydefgoto[] = { - -1, 5, 6, 7, 8, 9, 10, 11, 12, 13 + -1, 6, 7, 8, 9, 10, 11, 12, 13, 14 }; /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If @@ -565,28 +563,29 @@ static const yytype_int8 yydefgoto[] = number is the opposite. If YYTABLE_NINF, syntax error. */ static const yytype_uint8 yytable[] = { - 14, 15, 17, 1, 2, 18, 25, 26, 27, 19, - 3, 21, 22, 23, 24, 16, 4, 28, 18, 32, - 33, 20, 0, 29, 36, 37, 38, 34, 35, 31, - 30 + 15, 16, 20, 18, 1, 2, 19, 27, 28, 29, + 21, 3, 23, 24, 25, 26, 4, 5, 30, 20, + 34, 35, 22, 36, 37, 17, 38, 39, 40, 32, + 31, 0, 0, 0, 33 }; static const yytype_int8 yycheck[] = { - 1, 2, 0, 3, 4, 12, 5, 6, 7, 14, - 10, 8, 9, 3, 4, 3, 16, 11, 12, 21, - 22, 13, -1, 18, 25, 26, 27, 23, 24, 20, - 19 + 1, 2, 12, 4, 3, 4, 0, 5, 6, 7, + 14, 10, 8, 9, 3, 4, 15, 16, 11, 12, + 23, 24, 13, 25, 26, 3, 27, 28, 29, 21, + 20, -1, -1, -1, 22 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_uint8 yystos[] = { - 0, 3, 4, 10, 16, 18, 19, 20, 21, 22, - 23, 24, 25, 26, 25, 25, 19, 0, 12, 14, - 13, 8, 9, 3, 4, 5, 6, 7, 11, 20, - 21, 22, 23, 23, 24, 24, 25, 25, 25 + 0, 3, 4, 10, 15, 16, 18, 19, 20, 21, + 22, 23, 24, 25, 26, 25, 25, 19, 25, 0, + 12, 14, 13, 8, 9, 3, 4, 5, 6, 7, + 11, 20, 21, 22, 23, 23, 24, 24, 25, 25, + 25 }; /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ @@ -594,7 +593,7 @@ static const yytype_uint8 yyr1[] = { 0, 17, 18, 19, 19, 20, 20, 21, 21, 22, 22, 22, 23, 23, 23, 24, 24, 24, 24, 25, - 25, 25, 26, 26 + 25, 25, 25, 26, 26 }; /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ @@ -602,7 +601,7 @@ static const yytype_uint8 yyr2[] = { 0, 2, 1, 1, 3, 1, 3, 1, 3, 1, 3, 3, 1, 3, 3, 1, 3, 3, 3, 1, - 2, 2, 1, 3 + 2, 2, 2, 1, 3 }; @@ -618,22 +617,22 @@ static const yytype_uint8 yyr2[] = #define YYRECOVERING() (!!yyerrstatus) -#define YYBACKUP(Token, Value) \ -do \ - if (yychar == YYEMPTY) \ - { \ - yychar = (Token); \ - yylval = (Value); \ - YYPOPSTACK (yylen); \ - yystate = *yyssp; \ - goto yybackup; \ - } \ - else \ - { \ - yyerror (yyscanner, YY_("syntax error: cannot back up")); \ - YYERROR; \ - } \ -while (0) +#define YYBACKUP(Token, Value) \ + do \ + if (yychar == YYEMPTY) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + YYPOPSTACK (yylen); \ + yystate = *yyssp; \ + goto yybackup; \ + } \ + else \ + { \ + yyerror (yyscanner, YY_("syntax error: cannot back up")); \ + YYERROR; \ + } \ + while (0) /* Error token number */ #define YYTERROR 1 @@ -673,38 +672,38 @@ do { \ } while (0) -/*----------------------------------------. -| Print this symbol's value on YYOUTPUT. | -`----------------------------------------*/ +/*-----------------------------------. +| Print this symbol's value on YYO. | +`-----------------------------------*/ static void -yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, yyscan_t yyscanner) +yy_symbol_value_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep, yyscan_t yyscanner) { - FILE *yyo = yyoutput; - YYUSE (yyo); + FILE *yyoutput = yyo; + YYUSE (yyoutput); YYUSE (yyscanner); if (!yyvaluep) return; # ifdef YYPRINT if (yytype < YYNTOKENS) - YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); + YYPRINT (yyo, yytoknum[yytype], *yyvaluep); # endif YYUSE (yytype); } -/*--------------------------------. -| Print this symbol on YYOUTPUT. | -`--------------------------------*/ +/*---------------------------. +| Print this symbol on YYO. | +`---------------------------*/ static void -yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, yyscan_t yyscanner) +yy_symbol_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep, yyscan_t yyscanner) { - YYFPRINTF (yyoutput, "%s %s (", + YYFPRINTF (yyo, "%s %s (", yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]); - yy_symbol_value_print (yyoutput, yytype, yyvaluep, yyscanner); - YYFPRINTF (yyoutput, ")"); + yy_symbol_value_print (yyo, yytype, yyvaluep, yyscanner); + YYFPRINTF (yyo, ")"); } /*------------------------------------------------------------------. @@ -738,7 +737,7 @@ do { \ static void yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule, yyscan_t yyscanner) { - unsigned long int yylno = yyrline[yyrule]; + unsigned long yylno = yyrline[yyrule]; int yynrhs = yyr2[yyrule]; int yyi; YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", @@ -749,7 +748,7 @@ yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule, yyscan_t yysca YYFPRINTF (stderr, " $%d = ", yyi + 1); yy_symbol_print (stderr, yystos[yyssp[yyi + 1 - yynrhs]], - &(yyvsp[(yyi + 1) - (yynrhs)]) + &yyvsp[(yyi + 1) - (yynrhs)] , yyscanner); YYFPRINTF (stderr, "\n"); } @@ -853,7 +852,10 @@ yytnamerr (char *yyres, const char *yystr) case '\\': if (*++yyp != '\\') goto do_not_strip_quotes; - /* Fall through. */ + else + goto append; + + append: default: if (yyres) yyres[yyn] = *yyp; @@ -871,7 +873,7 @@ yytnamerr (char *yyres, const char *yystr) if (! yyres) return yystrlen (yystr); - return yystpcpy (yyres, yystr) - yyres; + return (YYSIZE_T) (yystpcpy (yyres, yystr) - yyres); } # endif @@ -949,10 +951,10 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, yyarg[yycount++] = yytname[yyx]; { YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]); - if (! (yysize <= yysize1 - && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) + if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM) + yysize = yysize1; + else return 2; - yysize = yysize1; } } } @@ -964,6 +966,7 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, case N: \ yyformat = S; \ break + default: /* Avoid compiler warnings. */ YYCASE_(0, YY_("syntax error")); YYCASE_(1, YY_("syntax error, unexpected %s")); YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); @@ -975,9 +978,10 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, { YYSIZE_T yysize1 = yysize + yystrlen (yyformat); - if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) + if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM) + yysize = yysize1; + else return 2; - yysize = yysize1; } if (*yymsg_alloc < yysize) @@ -1108,23 +1112,31 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); yychar = YYEMPTY; /* Cause a token to be read. */ goto yysetstate; + /*------------------------------------------------------------. -| yynewstate -- Push a new state, which is found in yystate. | +| yynewstate -- push a new state, which is found in yystate. | `------------------------------------------------------------*/ - yynewstate: +yynewstate: /* In all cases, when you get here, the value and location stacks have just been pushed. So pushing a state here evens the stacks. */ yyssp++; - yysetstate: - *yyssp = yystate; + +/*--------------------------------------------------------------------. +| yynewstate -- set current state (the top of the stack) to yystate. | +`--------------------------------------------------------------------*/ +yysetstate: + *yyssp = (yytype_int16) yystate; if (yyss + yystacksize - 1 <= yyssp) +#if !defined yyoverflow && !defined YYSTACK_RELOCATE + goto yyexhaustedlab; +#else { /* Get the current used size of the three stacks, in elements. */ - YYSIZE_T yysize = yyssp - yyss + 1; + YYSIZE_T yysize = (YYSIZE_T) (yyssp - yyss + 1); -#ifdef yyoverflow +# if defined yyoverflow { /* Give user a chance to reallocate the stack. Use copies of these so that the &'s don't force the real ones into @@ -1140,14 +1152,10 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); &yyss1, yysize * sizeof (*yyssp), &yyvs1, yysize * sizeof (*yyvsp), &yystacksize); - yyss = yyss1; yyvs = yyvs1; } -#else /* no yyoverflow */ -# ifndef YYSTACK_RELOCATE - goto yyexhaustedlab; -# else +# else /* defined YYSTACK_RELOCATE */ /* Extend the stack our own way. */ if (YYMAXDEPTH <= yystacksize) goto yyexhaustedlab; @@ -1163,22 +1171,22 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); goto yyexhaustedlab; YYSTACK_RELOCATE (yyss_alloc, yyss); YYSTACK_RELOCATE (yyvs_alloc, yyvs); -# undef YYSTACK_RELOCATE +# undef YYSTACK_RELOCATE if (yyss1 != yyssa) YYSTACK_FREE (yyss1); } # endif -#endif /* no yyoverflow */ yyssp = yyss + yysize - 1; yyvsp = yyvs + yysize - 1; YYDPRINTF ((stderr, "Stack size increased to %lu\n", - (unsigned long int) yystacksize)); + (unsigned long) yystacksize)); if (yyss + yystacksize - 1 <= yyssp) YYABORT; } +#endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */ YYDPRINTF ((stderr, "Entering state %d\n", yystate)); @@ -1187,11 +1195,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); goto yybackup; + /*-----------. | yybackup. | `-----------*/ yybackup: - /* Do appropriate processing given the current state. Read a lookahead token if we need one and don't already have one. */ @@ -1264,7 +1272,7 @@ yydefault: /*-----------------------------. -| yyreduce -- Do a reduction. | +| yyreduce -- do a reduction. | `-----------------------------*/ yyreduce: /* yyn is the number of a rule to reduce with. */ @@ -1285,186 +1293,194 @@ yyreduce: switch (yyn) { case 2: -#line 77 "cmExprParser.y" /* yacc.c:1646 */ +#line 77 "cmExprParser.y" /* yacc.c:1652 */ { cmExpr_yyget_extra(yyscanner)->SetResult((yyvsp[0].Number)); } -#line 1293 "cmExprParser.cxx" /* yacc.c:1646 */ +#line 1301 "cmExprParser.cxx" /* yacc.c:1652 */ break; case 3: -#line 82 "cmExprParser.y" /* yacc.c:1646 */ +#line 82 "cmExprParser.y" /* yacc.c:1652 */ { (yyval.Number) = (yyvsp[0].Number); } -#line 1301 "cmExprParser.cxx" /* yacc.c:1646 */ +#line 1309 "cmExprParser.cxx" /* yacc.c:1652 */ break; case 4: -#line 85 "cmExprParser.y" /* yacc.c:1646 */ +#line 85 "cmExprParser.y" /* yacc.c:1652 */ { (yyval.Number) = (yyvsp[-2].Number) | (yyvsp[0].Number); } -#line 1309 "cmExprParser.cxx" /* yacc.c:1646 */ +#line 1317 "cmExprParser.cxx" /* yacc.c:1652 */ break; case 5: -#line 90 "cmExprParser.y" /* yacc.c:1646 */ +#line 90 "cmExprParser.y" /* yacc.c:1652 */ { (yyval.Number) = (yyvsp[0].Number); } -#line 1317 "cmExprParser.cxx" /* yacc.c:1646 */ +#line 1325 "cmExprParser.cxx" /* yacc.c:1652 */ break; case 6: -#line 93 "cmExprParser.y" /* yacc.c:1646 */ +#line 93 "cmExprParser.y" /* yacc.c:1652 */ { (yyval.Number) = (yyvsp[-2].Number) ^ (yyvsp[0].Number); } -#line 1325 "cmExprParser.cxx" /* yacc.c:1646 */ +#line 1333 "cmExprParser.cxx" /* yacc.c:1652 */ break; case 7: -#line 98 "cmExprParser.y" /* yacc.c:1646 */ +#line 98 "cmExprParser.y" /* yacc.c:1652 */ { (yyval.Number) = (yyvsp[0].Number); } -#line 1333 "cmExprParser.cxx" /* yacc.c:1646 */ +#line 1341 "cmExprParser.cxx" /* yacc.c:1652 */ break; case 8: -#line 101 "cmExprParser.y" /* yacc.c:1646 */ +#line 101 "cmExprParser.y" /* yacc.c:1652 */ { (yyval.Number) = (yyvsp[-2].Number) & (yyvsp[0].Number); } -#line 1341 "cmExprParser.cxx" /* yacc.c:1646 */ +#line 1349 "cmExprParser.cxx" /* yacc.c:1652 */ break; case 9: -#line 106 "cmExprParser.y" /* yacc.c:1646 */ +#line 106 "cmExprParser.y" /* yacc.c:1652 */ { (yyval.Number) = (yyvsp[0].Number); } -#line 1349 "cmExprParser.cxx" /* yacc.c:1646 */ +#line 1357 "cmExprParser.cxx" /* yacc.c:1652 */ break; case 10: -#line 109 "cmExprParser.y" /* yacc.c:1646 */ +#line 109 "cmExprParser.y" /* yacc.c:1652 */ { (yyval.Number) = (yyvsp[-2].Number) << (yyvsp[0].Number); } -#line 1357 "cmExprParser.cxx" /* yacc.c:1646 */ +#line 1365 "cmExprParser.cxx" /* yacc.c:1652 */ break; case 11: -#line 112 "cmExprParser.y" /* yacc.c:1646 */ +#line 112 "cmExprParser.y" /* yacc.c:1652 */ { (yyval.Number) = (yyvsp[-2].Number) >> (yyvsp[0].Number); } -#line 1365 "cmExprParser.cxx" /* yacc.c:1646 */ +#line 1373 "cmExprParser.cxx" /* yacc.c:1652 */ break; case 12: -#line 117 "cmExprParser.y" /* yacc.c:1646 */ +#line 117 "cmExprParser.y" /* yacc.c:1652 */ { (yyval.Number) = (yyvsp[0].Number); } -#line 1373 "cmExprParser.cxx" /* yacc.c:1646 */ +#line 1381 "cmExprParser.cxx" /* yacc.c:1652 */ break; case 13: -#line 120 "cmExprParser.y" /* yacc.c:1646 */ +#line 120 "cmExprParser.y" /* yacc.c:1652 */ { (yyval.Number) = (yyvsp[-2].Number) + (yyvsp[0].Number); } -#line 1381 "cmExprParser.cxx" /* yacc.c:1646 */ +#line 1389 "cmExprParser.cxx" /* yacc.c:1652 */ break; case 14: -#line 123 "cmExprParser.y" /* yacc.c:1646 */ +#line 123 "cmExprParser.y" /* yacc.c:1652 */ { (yyval.Number) = (yyvsp[-2].Number) - (yyvsp[0].Number); } -#line 1389 "cmExprParser.cxx" /* yacc.c:1646 */ +#line 1397 "cmExprParser.cxx" /* yacc.c:1652 */ break; case 15: -#line 128 "cmExprParser.y" /* yacc.c:1646 */ +#line 128 "cmExprParser.y" /* yacc.c:1652 */ { (yyval.Number) = (yyvsp[0].Number); } -#line 1397 "cmExprParser.cxx" /* yacc.c:1646 */ +#line 1405 "cmExprParser.cxx" /* yacc.c:1652 */ break; case 16: -#line 131 "cmExprParser.y" /* yacc.c:1646 */ +#line 131 "cmExprParser.y" /* yacc.c:1652 */ { (yyval.Number) = (yyvsp[-2].Number) * (yyvsp[0].Number); } -#line 1405 "cmExprParser.cxx" /* yacc.c:1646 */ +#line 1413 "cmExprParser.cxx" /* yacc.c:1652 */ break; case 17: -#line 134 "cmExprParser.y" /* yacc.c:1646 */ +#line 134 "cmExprParser.y" /* yacc.c:1652 */ { if (yyvsp[0].Number == 0) { throw std::overflow_error("divide by zero"); } (yyval.Number) = (yyvsp[-2].Number) / (yyvsp[0].Number); } -#line 1416 "cmExprParser.cxx" /* yacc.c:1646 */ +#line 1424 "cmExprParser.cxx" /* yacc.c:1652 */ break; case 18: -#line 140 "cmExprParser.y" /* yacc.c:1646 */ +#line 140 "cmExprParser.y" /* yacc.c:1652 */ { (yyval.Number) = (yyvsp[-2].Number) % (yyvsp[0].Number); } -#line 1424 "cmExprParser.cxx" /* yacc.c:1646 */ +#line 1432 "cmExprParser.cxx" /* yacc.c:1652 */ break; case 19: -#line 145 "cmExprParser.y" /* yacc.c:1646 */ +#line 145 "cmExprParser.y" /* yacc.c:1652 */ { (yyval.Number) = (yyvsp[0].Number); } -#line 1432 "cmExprParser.cxx" /* yacc.c:1646 */ +#line 1440 "cmExprParser.cxx" /* yacc.c:1652 */ break; case 20: -#line 148 "cmExprParser.y" /* yacc.c:1646 */ +#line 148 "cmExprParser.y" /* yacc.c:1652 */ { (yyval.Number) = + (yyvsp[0].Number); } -#line 1440 "cmExprParser.cxx" /* yacc.c:1646 */ +#line 1448 "cmExprParser.cxx" /* yacc.c:1652 */ break; case 21: -#line 151 "cmExprParser.y" /* yacc.c:1646 */ +#line 151 "cmExprParser.y" /* yacc.c:1652 */ { (yyval.Number) = - (yyvsp[0].Number); } -#line 1448 "cmExprParser.cxx" /* yacc.c:1646 */ +#line 1456 "cmExprParser.cxx" /* yacc.c:1652 */ break; case 22: -#line 156 "cmExprParser.y" /* yacc.c:1646 */ +#line 154 "cmExprParser.y" /* yacc.c:1652 */ { - (yyval.Number) = (yyvsp[0].Number); + (yyval.Number) = ~ (yyvsp[0].Number); } -#line 1456 "cmExprParser.cxx" /* yacc.c:1646 */ +#line 1464 "cmExprParser.cxx" /* yacc.c:1652 */ break; case 23: -#line 159 "cmExprParser.y" /* yacc.c:1646 */ +#line 159 "cmExprParser.y" /* yacc.c:1652 */ + { + (yyval.Number) = (yyvsp[0].Number); + } +#line 1472 "cmExprParser.cxx" /* yacc.c:1652 */ + break; + + case 24: +#line 162 "cmExprParser.y" /* yacc.c:1652 */ { (yyval.Number) = (yyvsp[-1].Number); } -#line 1464 "cmExprParser.cxx" /* yacc.c:1646 */ +#line 1480 "cmExprParser.cxx" /* yacc.c:1652 */ break; -#line 1468 "cmExprParser.cxx" /* yacc.c:1646 */ +#line 1484 "cmExprParser.cxx" /* yacc.c:1652 */ default: break; } /* User semantic actions sometimes alter yychar, and that requires @@ -1489,14 +1505,13 @@ yyreduce: /* Now 'shift' the result of the reduction. Determine what state that goes to, based on the state we popped back to and the rule number reduced by. */ - - yyn = yyr1[yyn]; - - yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; - if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) - yystate = yytable[yystate]; - else - yystate = yydefgoto[yyn - YYNTOKENS]; + { + const int yylhs = yyr1[yyn] - YYNTOKENS; + const int yyi = yypgoto[yylhs] + *yyssp; + yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyssp + ? yytable[yyi] + : yydefgoto[yylhs]); + } goto yynewstate; @@ -1580,12 +1595,10 @@ yyerrlab: | yyerrorlab -- error raised explicitly by YYERROR. | `---------------------------------------------------*/ yyerrorlab: - - /* Pacify compilers like GCC when the user code never invokes - YYERROR and the label yyerrorlab therefore never appears in user - code. */ - if (/*CONSTCOND*/ 0) - goto yyerrorlab; + /* Pacify compilers when the user code never invokes YYERROR and the + label yyerrorlab therefore never appears in user code. */ + if (0) + YYERROR; /* Do not reclaim the symbols of the rule whose action triggered this YYERROR. */ @@ -1648,6 +1661,7 @@ yyacceptlab: yyresult = 0; goto yyreturn; + /*-----------------------------------. | yyabortlab -- YYABORT comes here. | `-----------------------------------*/ @@ -1655,6 +1669,7 @@ yyabortlab: yyresult = 1; goto yyreturn; + #if !defined yyoverflow || YYERROR_VERBOSE /*-------------------------------------------------. | yyexhaustedlab -- memory exhaustion comes here. | @@ -1665,6 +1680,10 @@ yyexhaustedlab: /* Fall through. */ #endif + +/*-----------------------------------------------------. +| yyreturn -- parsing is finished, return the result. | +`-----------------------------------------------------*/ yyreturn: if (yychar != YYEMPTY) { @@ -1694,7 +1713,7 @@ yyreturn: #endif return yyresult; } -#line 164 "cmExprParser.y" /* yacc.c:1906 */ +#line 167 "cmExprParser.y" /* yacc.c:1918 */ /* End of grammar */ diff --git a/Source/LexerParser/cmExprParser.y b/Source/LexerParser/cmExprParser.y index 2137473..7ae2118 100644 --- a/Source/LexerParser/cmExprParser.y +++ b/Source/LexerParser/cmExprParser.y @@ -151,6 +151,9 @@ unary: | exp_MINUS unary { $<Number>$ = - $<Number>2; } +| exp_NOT unary { + $<Number>$ = ~ $<Number>2; + } factor: exp_NUMBER { diff --git a/Source/LexerParser/cmExprParserTokens.h b/Source/LexerParser/cmExprParserTokens.h index 84b2bbd..5ffd7c5 100644 --- a/Source/LexerParser/cmExprParserTokens.h +++ b/Source/LexerParser/cmExprParserTokens.h @@ -1,8 +1,9 @@ -/* A Bison parser, made by GNU Bison 3.0.4. */ +/* A Bison parser, made by GNU Bison 3.3.2. */ /* Bison interface for Yacc-like parsers in C - Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc. + Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2019 Free Software Foundation, + Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -30,6 +31,9 @@ This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ +/* Undocumented macros, especially those whose name start with YY_, + are private implementation details. Do not rely on them. */ + #ifndef YY_CMEXPR_YY_CMEXPRPARSERTOKENS_H_INCLUDED # define YY_CMEXPR_YY_CMEXPRPARSERTOKENS_H_INCLUDED /* Debug traces. */ diff --git a/Source/LexerParser/cmFortranParser.cxx b/Source/LexerParser/cmFortranParser.cxx index 015cab9..2ca7927 100644 --- a/Source/LexerParser/cmFortranParser.cxx +++ b/Source/LexerParser/cmFortranParser.cxx @@ -1,8 +1,9 @@ -/* A Bison parser, made by GNU Bison 3.0.4. */ +/* A Bison parser, made by GNU Bison 3.3.2. */ /* Bison implementation for Yacc-like parsers in C - Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc. + Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2019 Free Software Foundation, + Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -40,11 +41,14 @@ define necessary library symbols; they are noted "INFRINGES ON USER NAME SPACE" below. */ +/* Undocumented macros, especially those whose name start with YY_, + are private implementation details. Do not rely on them. */ + /* Identify Bison output. */ #define YYBISON 1 /* Bison version. */ -#define YYBISON_VERSION "3.0.4" +#define YYBISON_VERSION "3.3.2" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" @@ -67,8 +71,8 @@ #define yynerrs cmFortran_yynerrs -/* Copy the first part of user declarations. */ -#line 1 "cmFortranParser.y" /* yacc.c:339 */ +/* First part of user prologue. */ +#line 1 "cmFortranParser.y" /* yacc.c:337 */ /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying file Copyright.txt or https://cmake.org/licensing for details. */ @@ -131,13 +135,16 @@ static void cmFortran_yyerror(yyscan_t yyscanner, const char* message) # pragma GCC diagnostic ignored "-Wconversion" #endif -#line 135 "cmFortranParser.cxx" /* yacc.c:339 */ - +#line 139 "cmFortranParser.cxx" /* yacc.c:337 */ # ifndef YY_NULLPTR -# if defined __cplusplus && 201103L <= __cplusplus -# define YY_NULLPTR nullptr +# if defined __cplusplus +# if 201103L <= __cplusplus +# define YY_NULLPTR nullptr +# else +# define YY_NULLPTR 0 +# endif # else -# define YY_NULLPTR 0 +# define YY_NULLPTR ((void*)0) # endif # endif @@ -251,11 +258,11 @@ extern int cmFortran_yydebug; union YYSTYPE { -#line 73 "cmFortranParser.y" /* yacc.c:355 */ +#line 73 "cmFortranParser.y" /* yacc.c:352 */ char* string; -#line 259 "cmFortranParser.cxx" /* yacc.c:355 */ +#line 266 "cmFortranParser.cxx" /* yacc.c:352 */ }; typedef union YYSTYPE YYSTYPE; @@ -269,9 +276,7 @@ int cmFortran_yyparse (yyscan_t yyscanner); #endif /* !YY_CMFORTRAN_YY_CMFORTRANPARSERTOKENS_H_INCLUDED */ -/* Copy the second part of user declarations. */ -#line 275 "cmFortranParser.cxx" /* yacc.c:358 */ #ifdef short # undef short @@ -292,13 +297,13 @@ typedef signed char yytype_int8; #ifdef YYTYPE_UINT16 typedef YYTYPE_UINT16 yytype_uint16; #else -typedef unsigned short int yytype_uint16; +typedef unsigned short yytype_uint16; #endif #ifdef YYTYPE_INT16 typedef YYTYPE_INT16 yytype_int16; #else -typedef short int yytype_int16; +typedef short yytype_int16; #endif #ifndef YYSIZE_T @@ -310,7 +315,7 @@ typedef short int yytype_int16; # include <stddef.h> /* INFRINGES ON USER NAME SPACE */ # define YYSIZE_T size_t # else -# define YYSIZE_T unsigned int +# define YYSIZE_T unsigned # endif #endif @@ -346,15 +351,6 @@ typedef short int yytype_int16; # define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__)) #endif -#if !defined _Noreturn \ - && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112) -# if defined _MSC_VER && 1200 <= _MSC_VER -# define _Noreturn __declspec (noreturn) -# else -# define _Noreturn YY_ATTRIBUTE ((__noreturn__)) -# endif -#endif - /* Suppress unused-variable warnings by "using" E. */ #if ! defined lint || defined __GNUC__ # define YYUSE(E) ((void) (E)) @@ -362,7 +358,7 @@ typedef short int yytype_int16; # define YYUSE(E) /* empty */ #endif -#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ +#if defined __GNUC__ && ! defined __ICC && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ /* Suppress an incorrect diagnostic about yylval being uninitialized. */ # define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ _Pragma ("GCC diagnostic push") \ @@ -524,16 +520,16 @@ union yyalloc /* YYNSTATES -- Number of states. */ #define YYNSTATES 126 -/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned - by yylex, with out-of-bounds checking. */ #define YYUNDEFTOK 2 #define YYMAXUTOK 295 +/* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM + as returned by yylex, with out-of-bounds checking. */ #define YYTRANSLATE(YYX) \ - ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + ((unsigned) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) /* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM - as returned by yylex, without out-of-bounds checking. */ + as returned by yylex. */ static const yytype_uint8 yytranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -863,22 +859,22 @@ static const yytype_uint8 yyr2[] = #define YYRECOVERING() (!!yyerrstatus) -#define YYBACKUP(Token, Value) \ -do \ - if (yychar == YYEMPTY) \ - { \ - yychar = (Token); \ - yylval = (Value); \ - YYPOPSTACK (yylen); \ - yystate = *yyssp; \ - goto yybackup; \ - } \ - else \ - { \ - yyerror (yyscanner, YY_("syntax error: cannot back up")); \ - YYERROR; \ - } \ -while (0) +#define YYBACKUP(Token, Value) \ + do \ + if (yychar == YYEMPTY) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + YYPOPSTACK (yylen); \ + yystate = *yyssp; \ + goto yybackup; \ + } \ + else \ + { \ + yyerror (yyscanner, YY_("syntax error: cannot back up")); \ + YYERROR; \ + } \ + while (0) /* Error token number */ #define YYTERROR 1 @@ -918,38 +914,38 @@ do { \ } while (0) -/*----------------------------------------. -| Print this symbol's value on YYOUTPUT. | -`----------------------------------------*/ +/*-----------------------------------. +| Print this symbol's value on YYO. | +`-----------------------------------*/ static void -yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, yyscan_t yyscanner) +yy_symbol_value_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep, yyscan_t yyscanner) { - FILE *yyo = yyoutput; - YYUSE (yyo); + FILE *yyoutput = yyo; + YYUSE (yyoutput); YYUSE (yyscanner); if (!yyvaluep) return; # ifdef YYPRINT if (yytype < YYNTOKENS) - YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); + YYPRINT (yyo, yytoknum[yytype], *yyvaluep); # endif YYUSE (yytype); } -/*--------------------------------. -| Print this symbol on YYOUTPUT. | -`--------------------------------*/ +/*---------------------------. +| Print this symbol on YYO. | +`---------------------------*/ static void -yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, yyscan_t yyscanner) +yy_symbol_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep, yyscan_t yyscanner) { - YYFPRINTF (yyoutput, "%s %s (", + YYFPRINTF (yyo, "%s %s (", yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]); - yy_symbol_value_print (yyoutput, yytype, yyvaluep, yyscanner); - YYFPRINTF (yyoutput, ")"); + yy_symbol_value_print (yyo, yytype, yyvaluep, yyscanner); + YYFPRINTF (yyo, ")"); } /*------------------------------------------------------------------. @@ -983,7 +979,7 @@ do { \ static void yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule, yyscan_t yyscanner) { - unsigned long int yylno = yyrline[yyrule]; + unsigned long yylno = yyrline[yyrule]; int yynrhs = yyr2[yyrule]; int yyi; YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", @@ -994,7 +990,7 @@ yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule, yyscan_t yysca YYFPRINTF (stderr, " $%d = ", yyi + 1); yy_symbol_print (stderr, yystos[yyssp[yyi + 1 - yynrhs]], - &(yyvsp[(yyi + 1) - (yynrhs)]) + &yyvsp[(yyi + 1) - (yynrhs)] , yyscanner); YYFPRINTF (stderr, "\n"); } @@ -1098,7 +1094,10 @@ yytnamerr (char *yyres, const char *yystr) case '\\': if (*++yyp != '\\') goto do_not_strip_quotes; - /* Fall through. */ + else + goto append; + + append: default: if (yyres) yyres[yyn] = *yyp; @@ -1116,7 +1115,7 @@ yytnamerr (char *yyres, const char *yystr) if (! yyres) return yystrlen (yystr); - return yystpcpy (yyres, yystr) - yyres; + return (YYSIZE_T) (yystpcpy (yyres, yystr) - yyres); } # endif @@ -1194,10 +1193,10 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, yyarg[yycount++] = yytname[yyx]; { YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]); - if (! (yysize <= yysize1 - && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) + if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM) + yysize = yysize1; + else return 2; - yysize = yysize1; } } } @@ -1209,6 +1208,7 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, case N: \ yyformat = S; \ break + default: /* Avoid compiler warnings. */ YYCASE_(0, YY_("syntax error")); YYCASE_(1, YY_("syntax error, unexpected %s")); YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); @@ -1220,9 +1220,10 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, { YYSIZE_T yysize1 = yysize + yystrlen (yyformat); - if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) + if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM) + yysize = yysize1; + else return 2; - yysize = yysize1; } if (*yymsg_alloc < yysize) @@ -1353,23 +1354,31 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); yychar = YYEMPTY; /* Cause a token to be read. */ goto yysetstate; + /*------------------------------------------------------------. -| yynewstate -- Push a new state, which is found in yystate. | +| yynewstate -- push a new state, which is found in yystate. | `------------------------------------------------------------*/ - yynewstate: +yynewstate: /* In all cases, when you get here, the value and location stacks have just been pushed. So pushing a state here evens the stacks. */ yyssp++; - yysetstate: - *yyssp = yystate; + +/*--------------------------------------------------------------------. +| yynewstate -- set current state (the top of the stack) to yystate. | +`--------------------------------------------------------------------*/ +yysetstate: + *yyssp = (yytype_int16) yystate; if (yyss + yystacksize - 1 <= yyssp) +#if !defined yyoverflow && !defined YYSTACK_RELOCATE + goto yyexhaustedlab; +#else { /* Get the current used size of the three stacks, in elements. */ - YYSIZE_T yysize = yyssp - yyss + 1; + YYSIZE_T yysize = (YYSIZE_T) (yyssp - yyss + 1); -#ifdef yyoverflow +# if defined yyoverflow { /* Give user a chance to reallocate the stack. Use copies of these so that the &'s don't force the real ones into @@ -1385,14 +1394,10 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); &yyss1, yysize * sizeof (*yyssp), &yyvs1, yysize * sizeof (*yyvsp), &yystacksize); - yyss = yyss1; yyvs = yyvs1; } -#else /* no yyoverflow */ -# ifndef YYSTACK_RELOCATE - goto yyexhaustedlab; -# else +# else /* defined YYSTACK_RELOCATE */ /* Extend the stack our own way. */ if (YYMAXDEPTH <= yystacksize) goto yyexhaustedlab; @@ -1408,22 +1413,22 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); goto yyexhaustedlab; YYSTACK_RELOCATE (yyss_alloc, yyss); YYSTACK_RELOCATE (yyvs_alloc, yyvs); -# undef YYSTACK_RELOCATE +# undef YYSTACK_RELOCATE if (yyss1 != yyssa) YYSTACK_FREE (yyss1); } # endif -#endif /* no yyoverflow */ yyssp = yyss + yysize - 1; yyvsp = yyvs + yysize - 1; YYDPRINTF ((stderr, "Stack size increased to %lu\n", - (unsigned long int) yystacksize)); + (unsigned long) yystacksize)); if (yyss + yystacksize - 1 <= yyssp) YYABORT; } +#endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */ YYDPRINTF ((stderr, "Entering state %d\n", yystate)); @@ -1432,11 +1437,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); goto yybackup; + /*-----------. | yybackup. | `-----------*/ yybackup: - /* Do appropriate processing given the current state. Read a lookahead token if we need one and don't already have one. */ @@ -1509,7 +1514,7 @@ yydefault: /*-----------------------------. -| yyreduce -- Do a reduction. | +| yyreduce -- do a reduction. | `-----------------------------*/ yyreduce: /* yyn is the number of a rule to reduce with. */ @@ -1530,26 +1535,26 @@ yyreduce: switch (yyn) { case 4: -#line 104 "cmFortranParser.y" /* yacc.c:1646 */ +#line 104 "cmFortranParser.y" /* yacc.c:1652 */ { cmFortranParser* parser = cmFortran_yyget_extra(yyscanner); cmFortranParser_SetInInterface(parser, true); } -#line 1539 "cmFortranParser.cxx" /* yacc.c:1646 */ +#line 1544 "cmFortranParser.cxx" /* yacc.c:1652 */ break; case 5: -#line 108 "cmFortranParser.y" /* yacc.c:1646 */ +#line 108 "cmFortranParser.y" /* yacc.c:1652 */ { cmFortranParser* parser = cmFortran_yyget_extra(yyscanner); cmFortranParser_RuleUse(parser, (yyvsp[-2].string)); free((yyvsp[-2].string)); } -#line 1549 "cmFortranParser.cxx" /* yacc.c:1646 */ +#line 1554 "cmFortranParser.cxx" /* yacc.c:1652 */ break; case 6: -#line 113 "cmFortranParser.y" /* yacc.c:1646 */ +#line 113 "cmFortranParser.y" /* yacc.c:1652 */ { cmFortranParser* parser = cmFortran_yyget_extra(yyscanner); if (cmsysString_strcasecmp((yyvsp[-2].string), "function") != 0 && @@ -1559,22 +1564,22 @@ yyreduce: } free((yyvsp[-2].string)); } -#line 1563 "cmFortranParser.cxx" /* yacc.c:1646 */ +#line 1568 "cmFortranParser.cxx" /* yacc.c:1652 */ break; case 7: -#line 122 "cmFortranParser.y" /* yacc.c:1646 */ +#line 122 "cmFortranParser.y" /* yacc.c:1652 */ { cmFortranParser* parser = cmFortran_yyget_extra(yyscanner); cmFortranParser_RuleSubmodule(parser, (yyvsp[-4].string), (yyvsp[-2].string)); free((yyvsp[-4].string)); free((yyvsp[-2].string)); } -#line 1574 "cmFortranParser.cxx" /* yacc.c:1646 */ +#line 1579 "cmFortranParser.cxx" /* yacc.c:1652 */ break; case 8: -#line 128 "cmFortranParser.y" /* yacc.c:1646 */ +#line 128 "cmFortranParser.y" /* yacc.c:1652 */ { cmFortranParser* parser = cmFortran_yyget_extra(yyscanner); cmFortranParser_RuleSubmoduleNested(parser, (yyvsp[-6].string), (yyvsp[-4].string), (yyvsp[-2].string)); @@ -1582,40 +1587,40 @@ yyreduce: free((yyvsp[-4].string)); free((yyvsp[-2].string)); } -#line 1586 "cmFortranParser.cxx" /* yacc.c:1646 */ +#line 1591 "cmFortranParser.cxx" /* yacc.c:1652 */ break; case 9: -#line 135 "cmFortranParser.y" /* yacc.c:1646 */ +#line 135 "cmFortranParser.y" /* yacc.c:1652 */ { cmFortranParser* parser = cmFortran_yyget_extra(yyscanner); cmFortranParser_SetInInterface(parser, true); free((yyvsp[-2].string)); } -#line 1596 "cmFortranParser.cxx" /* yacc.c:1646 */ +#line 1601 "cmFortranParser.cxx" /* yacc.c:1652 */ break; case 10: -#line 140 "cmFortranParser.y" /* yacc.c:1646 */ +#line 140 "cmFortranParser.y" /* yacc.c:1652 */ { cmFortranParser* parser = cmFortran_yyget_extra(yyscanner); cmFortranParser_SetInInterface(parser, false); } -#line 1605 "cmFortranParser.cxx" /* yacc.c:1646 */ +#line 1610 "cmFortranParser.cxx" /* yacc.c:1652 */ break; case 11: -#line 144 "cmFortranParser.y" /* yacc.c:1646 */ +#line 144 "cmFortranParser.y" /* yacc.c:1652 */ { cmFortranParser* parser = cmFortran_yyget_extra(yyscanner); cmFortranParser_RuleUse(parser, (yyvsp[-2].string)); free((yyvsp[-2].string)); } -#line 1615 "cmFortranParser.cxx" /* yacc.c:1646 */ +#line 1620 "cmFortranParser.cxx" /* yacc.c:1652 */ break; case 12: -#line 149 "cmFortranParser.y" /* yacc.c:1646 */ +#line 149 "cmFortranParser.y" /* yacc.c:1652 */ { if (cmsysString_strcasecmp((yyvsp[-4].string), "non_intrinsic") == 0) { cmFortranParser* parser = cmFortran_yyget_extra(yyscanner); @@ -1624,139 +1629,139 @@ yyreduce: free((yyvsp[-4].string)); free((yyvsp[-2].string)); } -#line 1628 "cmFortranParser.cxx" /* yacc.c:1646 */ +#line 1633 "cmFortranParser.cxx" /* yacc.c:1652 */ break; case 13: -#line 157 "cmFortranParser.y" /* yacc.c:1646 */ +#line 157 "cmFortranParser.y" /* yacc.c:1652 */ { cmFortranParser* parser = cmFortran_yyget_extra(yyscanner); cmFortranParser_RuleInclude(parser, (yyvsp[-2].string)); free((yyvsp[-2].string)); } -#line 1638 "cmFortranParser.cxx" /* yacc.c:1646 */ +#line 1643 "cmFortranParser.cxx" /* yacc.c:1652 */ break; case 14: -#line 162 "cmFortranParser.y" /* yacc.c:1646 */ +#line 162 "cmFortranParser.y" /* yacc.c:1652 */ { cmFortranParser* parser = cmFortran_yyget_extra(yyscanner); cmFortranParser_RuleLineDirective(parser, (yyvsp[-2].string)); free((yyvsp[-2].string)); } -#line 1648 "cmFortranParser.cxx" /* yacc.c:1646 */ +#line 1653 "cmFortranParser.cxx" /* yacc.c:1652 */ break; case 15: -#line 167 "cmFortranParser.y" /* yacc.c:1646 */ +#line 167 "cmFortranParser.y" /* yacc.c:1652 */ { cmFortranParser* parser = cmFortran_yyget_extra(yyscanner); cmFortranParser_RuleInclude(parser, (yyvsp[-2].string)); free((yyvsp[-2].string)); } -#line 1658 "cmFortranParser.cxx" /* yacc.c:1646 */ +#line 1663 "cmFortranParser.cxx" /* yacc.c:1652 */ break; case 16: -#line 172 "cmFortranParser.y" /* yacc.c:1646 */ +#line 172 "cmFortranParser.y" /* yacc.c:1652 */ { cmFortranParser* parser = cmFortran_yyget_extra(yyscanner); cmFortranParser_RuleInclude(parser, (yyvsp[-2].string)); free((yyvsp[-2].string)); } -#line 1668 "cmFortranParser.cxx" /* yacc.c:1646 */ +#line 1673 "cmFortranParser.cxx" /* yacc.c:1652 */ break; case 17: -#line 177 "cmFortranParser.y" /* yacc.c:1646 */ +#line 177 "cmFortranParser.y" /* yacc.c:1652 */ { cmFortranParser* parser = cmFortran_yyget_extra(yyscanner); cmFortranParser_RuleDefine(parser, (yyvsp[-2].string)); free((yyvsp[-2].string)); } -#line 1678 "cmFortranParser.cxx" /* yacc.c:1646 */ +#line 1683 "cmFortranParser.cxx" /* yacc.c:1652 */ break; case 18: -#line 182 "cmFortranParser.y" /* yacc.c:1646 */ +#line 182 "cmFortranParser.y" /* yacc.c:1652 */ { cmFortranParser* parser = cmFortran_yyget_extra(yyscanner); cmFortranParser_RuleUndef(parser, (yyvsp[-2].string)); free((yyvsp[-2].string)); } -#line 1688 "cmFortranParser.cxx" /* yacc.c:1646 */ +#line 1693 "cmFortranParser.cxx" /* yacc.c:1652 */ break; case 19: -#line 187 "cmFortranParser.y" /* yacc.c:1646 */ +#line 187 "cmFortranParser.y" /* yacc.c:1652 */ { cmFortranParser* parser = cmFortran_yyget_extra(yyscanner); cmFortranParser_RuleIfdef(parser, (yyvsp[-2].string)); free((yyvsp[-2].string)); } -#line 1698 "cmFortranParser.cxx" /* yacc.c:1646 */ +#line 1703 "cmFortranParser.cxx" /* yacc.c:1652 */ break; case 20: -#line 192 "cmFortranParser.y" /* yacc.c:1646 */ +#line 192 "cmFortranParser.y" /* yacc.c:1652 */ { cmFortranParser* parser = cmFortran_yyget_extra(yyscanner); cmFortranParser_RuleIfndef(parser, (yyvsp[-2].string)); free((yyvsp[-2].string)); } -#line 1708 "cmFortranParser.cxx" /* yacc.c:1646 */ +#line 1713 "cmFortranParser.cxx" /* yacc.c:1652 */ break; case 21: -#line 197 "cmFortranParser.y" /* yacc.c:1646 */ +#line 197 "cmFortranParser.y" /* yacc.c:1652 */ { cmFortranParser* parser = cmFortran_yyget_extra(yyscanner); cmFortranParser_RuleIf(parser); } -#line 1717 "cmFortranParser.cxx" /* yacc.c:1646 */ +#line 1722 "cmFortranParser.cxx" /* yacc.c:1652 */ break; case 22: -#line 201 "cmFortranParser.y" /* yacc.c:1646 */ +#line 201 "cmFortranParser.y" /* yacc.c:1652 */ { cmFortranParser* parser = cmFortran_yyget_extra(yyscanner); cmFortranParser_RuleElif(parser); } -#line 1726 "cmFortranParser.cxx" /* yacc.c:1646 */ +#line 1731 "cmFortranParser.cxx" /* yacc.c:1652 */ break; case 23: -#line 205 "cmFortranParser.y" /* yacc.c:1646 */ +#line 205 "cmFortranParser.y" /* yacc.c:1652 */ { cmFortranParser* parser = cmFortran_yyget_extra(yyscanner); cmFortranParser_RuleElse(parser); } -#line 1735 "cmFortranParser.cxx" /* yacc.c:1646 */ +#line 1740 "cmFortranParser.cxx" /* yacc.c:1652 */ break; case 24: -#line 209 "cmFortranParser.y" /* yacc.c:1646 */ +#line 209 "cmFortranParser.y" /* yacc.c:1652 */ { cmFortranParser* parser = cmFortran_yyget_extra(yyscanner); cmFortranParser_RuleEndif(parser); } -#line 1744 "cmFortranParser.cxx" /* yacc.c:1646 */ +#line 1749 "cmFortranParser.cxx" /* yacc.c:1652 */ break; case 48: -#line 231 "cmFortranParser.y" /* yacc.c:1646 */ +#line 231 "cmFortranParser.y" /* yacc.c:1652 */ { free ((yyvsp[0].string)); } -#line 1750 "cmFortranParser.cxx" /* yacc.c:1646 */ +#line 1755 "cmFortranParser.cxx" /* yacc.c:1652 */ break; case 55: -#line 238 "cmFortranParser.y" /* yacc.c:1646 */ +#line 238 "cmFortranParser.y" /* yacc.c:1652 */ { free ((yyvsp[0].string)); } -#line 1756 "cmFortranParser.cxx" /* yacc.c:1646 */ +#line 1761 "cmFortranParser.cxx" /* yacc.c:1652 */ break; -#line 1760 "cmFortranParser.cxx" /* yacc.c:1646 */ +#line 1765 "cmFortranParser.cxx" /* yacc.c:1652 */ default: break; } /* User semantic actions sometimes alter yychar, and that requires @@ -1781,14 +1786,13 @@ yyreduce: /* Now 'shift' the result of the reduction. Determine what state that goes to, based on the state we popped back to and the rule number reduced by. */ - - yyn = yyr1[yyn]; - - yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; - if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) - yystate = yytable[yystate]; - else - yystate = yydefgoto[yyn - YYNTOKENS]; + { + const int yylhs = yyr1[yyn] - YYNTOKENS; + const int yyi = yypgoto[yylhs] + *yyssp; + yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyssp + ? yytable[yyi] + : yydefgoto[yylhs]); + } goto yynewstate; @@ -1872,12 +1876,10 @@ yyerrlab: | yyerrorlab -- error raised explicitly by YYERROR. | `---------------------------------------------------*/ yyerrorlab: - - /* Pacify compilers like GCC when the user code never invokes - YYERROR and the label yyerrorlab therefore never appears in user - code. */ - if (/*CONSTCOND*/ 0) - goto yyerrorlab; + /* Pacify compilers when the user code never invokes YYERROR and the + label yyerrorlab therefore never appears in user code. */ + if (0) + YYERROR; /* Do not reclaim the symbols of the rule whose action triggered this YYERROR. */ @@ -1940,6 +1942,7 @@ yyacceptlab: yyresult = 0; goto yyreturn; + /*-----------------------------------. | yyabortlab -- YYABORT comes here. | `-----------------------------------*/ @@ -1947,6 +1950,7 @@ yyabortlab: yyresult = 1; goto yyreturn; + #if !defined yyoverflow || YYERROR_VERBOSE /*-------------------------------------------------. | yyexhaustedlab -- memory exhaustion comes here. | @@ -1957,6 +1961,10 @@ yyexhaustedlab: /* Fall through. */ #endif + +/*-----------------------------------------------------. +| yyreturn -- parsing is finished, return the result. | +`-----------------------------------------------------*/ yyreturn: if (yychar != YYEMPTY) { @@ -1986,6 +1994,6 @@ yyreturn: #endif return yyresult; } -#line 249 "cmFortranParser.y" /* yacc.c:1906 */ +#line 249 "cmFortranParser.y" /* yacc.c:1918 */ /* End of grammar */ diff --git a/Source/LexerParser/cmFortranParserTokens.h b/Source/LexerParser/cmFortranParserTokens.h index 29c6d60..0da4c1c 100644 --- a/Source/LexerParser/cmFortranParserTokens.h +++ b/Source/LexerParser/cmFortranParserTokens.h @@ -1,8 +1,9 @@ -/* A Bison parser, made by GNU Bison 3.0.4. */ +/* A Bison parser, made by GNU Bison 3.3.2. */ /* Bison interface for Yacc-like parsers in C - Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc. + Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2019 Free Software Foundation, + Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -30,6 +31,9 @@ This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ +/* Undocumented macros, especially those whose name start with YY_, + are private implementation details. Do not rely on them. */ + #ifndef YY_CMFORTRAN_YY_CMFORTRANPARSERTOKENS_H_INCLUDED # define YY_CMFORTRAN_YY_CMFORTRANPARSERTOKENS_H_INCLUDED /* Debug traces. */ @@ -130,11 +134,11 @@ extern int cmFortran_yydebug; union YYSTYPE { -#line 73 "cmFortranParser.y" /* yacc.c:1909 */ +#line 73 "cmFortranParser.y" /* yacc.c:1921 */ char* string; -#line 138 "cmFortranParserTokens.h" /* yacc.c:1909 */ +#line 142 "cmFortranParserTokens.h" /* yacc.c:1921 */ }; typedef union YYSTYPE YYSTYPE; diff --git a/Source/QtDialog/CMakeSetup.cxx b/Source/QtDialog/CMakeSetup.cxx index c9ebba8..287a482 100644 --- a/Source/QtDialog/CMakeSetup.cxx +++ b/Source/QtDialog/CMakeSetup.cxx @@ -6,6 +6,7 @@ #include "cmAlgorithms.h" #include "cmDocumentation.h" #include "cmDocumentationEntry.h" +#include "cmStringAlgorithms.h" #include "cmVersion.h" #include "cmake.h" #include "cmsys/CommandLineArguments.hxx" 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/QCMake.cxx b/Source/QtDialog/QCMake.cxx index f357f90..ece3307 100644 --- a/Source/QtDialog/QCMake.cxx +++ b/Source/QtDialog/QCMake.cxx @@ -7,6 +7,7 @@ #include "cmExternalMakefileProjectGenerator.h" #include "cmState.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #ifdef Q_OS_WIN @@ -312,7 +313,7 @@ QCMakePropertyList QCMake::properties() const prop.Advanced = state->GetCacheEntryPropertyAsBool(key, "ADVANCED"); if (t == cmStateEnums::BOOL) { prop.Type = QCMakeProperty::BOOL; - prop.Value = cmSystemTools::IsOn(cachedValue); + prop.Value = cmIsOn(cachedValue); } else if (t == cmStateEnums::PATH) { prop.Type = QCMakeProperty::PATH; } else if (t == cmStateEnums::FILEPATH) { 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/cmAddCompileDefinitionsCommand.cxx b/Source/cmAddCompileDefinitionsCommand.cxx index 0474819..b00a4a7 100644 --- a/Source/cmAddCompileDefinitionsCommand.cxx +++ b/Source/cmAddCompileDefinitionsCommand.cxx @@ -2,19 +2,15 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmAddCompileDefinitionsCommand.h" +#include "cmExecutionStatus.h" #include "cmMakefile.h" -class cmExecutionStatus; - -bool cmAddCompileDefinitionsCommand::InitialPass( - std::vector<std::string> const& args, cmExecutionStatus&) +bool cmAddCompileDefinitionsCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { - if (args.empty()) { - return true; - } - + cmMakefile& mf = status.GetMakefile(); for (std::string const& i : args) { - this->Makefile->AddCompileDefinition(i); + mf.AddCompileDefinition(i); } return true; } diff --git a/Source/cmAddCompileDefinitionsCommand.h b/Source/cmAddCompileDefinitionsCommand.h index e985dca..4bd621c 100644 --- a/Source/cmAddCompileDefinitionsCommand.h +++ b/Source/cmAddCompileDefinitionsCommand.h @@ -8,24 +8,9 @@ #include <string> #include <vector> -#include "cmCommand.h" - class cmExecutionStatus; -class cmAddCompileDefinitionsCommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - cmCommand* Clone() override { return new cmAddCompileDefinitionsCommand; } - - /** - * 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 cmAddCompileDefinitionsCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmAddCompileOptionsCommand.cxx b/Source/cmAddCompileOptionsCommand.cxx index 412fb38..8ccb512 100644 --- a/Source/cmAddCompileOptionsCommand.cxx +++ b/Source/cmAddCompileOptionsCommand.cxx @@ -2,19 +2,15 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmAddCompileOptionsCommand.h" +#include "cmExecutionStatus.h" #include "cmMakefile.h" -class cmExecutionStatus; - -bool cmAddCompileOptionsCommand::InitialPass( - std::vector<std::string> const& args, cmExecutionStatus&) +bool cmAddCompileOptionsCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { - if (args.empty()) { - return true; - } - + cmMakefile& mf = status.GetMakefile(); for (std::string const& i : args) { - this->Makefile->AddCompileOption(i); + mf.AddCompileOption(i); } return true; } diff --git a/Source/cmAddCompileOptionsCommand.h b/Source/cmAddCompileOptionsCommand.h index 3d53d09..b172412 100644 --- a/Source/cmAddCompileOptionsCommand.h +++ b/Source/cmAddCompileOptionsCommand.h @@ -8,24 +8,9 @@ #include <string> #include <vector> -#include "cmCommand.h" - class cmExecutionStatus; -class cmAddCompileOptionsCommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - cmCommand* Clone() override { return new cmAddCompileOptionsCommand; } - - /** - * 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 cmAddCompileOptionsCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmAddCustomCommandCommand.cxx b/Source/cmAddCustomCommandCommand.cxx index 0be3c85..d2330e1 100644 --- a/Source/cmAddCustomCommandCommand.cxx +++ b/Source/cmAddCustomCommandCommand.cxx @@ -8,33 +8,44 @@ #include "cmCustomCommand.h" #include "cmCustomCommandLines.h" +#include "cmExecutionStatus.h" #include "cmGlobalGenerator.h" #include "cmMakefile.h" #include "cmMessageType.h" #include "cmPolicies.h" #include "cmSourceFile.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmTarget.h" -class cmExecutionStatus; +static bool cmAddCustomCommandCommandCheckOutputs( + const std::vector<std::string>& outputs, cmExecutionStatus& status); -// cmAddCustomCommandCommand -bool cmAddCustomCommandCommand::InitialPass( - std::vector<std::string> const& args, cmExecutionStatus&) +bool cmAddCustomCommandCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { /* Let's complain at the end of this function about the lack of a particular arg. For the moment, let's say that COMMAND, and either TARGET or SOURCE are required. */ if (args.size() < 4) { - this->SetError("called with wrong number of arguments."); + status.SetError("called with wrong number of arguments."); return false; } - std::string source, target, main_dependency, working, depfile, job_pool; + cmMakefile& mf = status.GetMakefile(); + 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; @@ -95,30 +106,29 @@ bool cmAddCustomCommandCommand::InitialPass( MAKE_STATIC_KEYWORD(VERBATIM); MAKE_STATIC_KEYWORD(WORKING_DIRECTORY); #undef MAKE_STATIC_KEYWORD - static std::unordered_set<std::string> keywords; - if (keywords.empty()) { - keywords.insert(keyAPPEND); - keywords.insert(keyARGS); - keywords.insert(keyBYPRODUCTS); - keywords.insert(keyCOMMAND); - keywords.insert(keyCOMMAND_EXPAND_LISTS); - keywords.insert(keyCOMMENT); - keywords.insert(keyDEPENDS); - keywords.insert(keyDEPFILE); - keywords.insert(keyIMPLICIT_DEPENDS); - keywords.insert(keyJOB_POOL); - keywords.insert(keyMAIN_DEPENDENCY); - keywords.insert(keyOUTPUT); - keywords.insert(keyOUTPUTS); - keywords.insert(keyPOST_BUILD); - keywords.insert(keyPRE_BUILD); - keywords.insert(keyPRE_LINK); - keywords.insert(keySOURCE); - keywords.insert(keyTARGET); - keywords.insert(keyUSES_TERMINAL); - keywords.insert(keyVERBATIM); - keywords.insert(keyWORKING_DIRECTORY); - } + static std::unordered_set<std::string> const keywords{ + keyAPPEND, + keyARGS, + keyBYPRODUCTS, + keyCOMMAND, + keyCOMMAND_EXPAND_LISTS, + keyCOMMENT, + keyDEPENDS, + keyDEPFILE, + keyIMPLICIT_DEPENDS, + keyJOB_POOL, + keyMAIN_DEPENDENCY, + keyOUTPUT, + keyOUTPUTS, + keyPOST_BUILD, + keyPRE_BUILD, + keyPRE_LINK, + keySOURCE, + keyTARGET, + keyUSES_TERMINAL, + keyVERBATIM, + keyWORKING_DIRECTORY + }; for (std::string const& copy : args) { if (keywords.count(copy)) { @@ -168,9 +178,9 @@ bool cmAddCustomCommandCommand::InitialPass( doing = doing_comment; } else if (copy == keyDEPFILE) { doing = doing_depfile; - if (this->Makefile->GetGlobalGenerator()->GetName() != "Ninja") { - this->SetError("Option DEPFILE not supported by " + - this->Makefile->GetGlobalGenerator()->GetName()); + if (mf.GetGlobalGenerator()->GetName() != "Ninja") { + status.SetError("Option DEPFILE not supported by " + + mf.GetGlobalGenerator()->GetName()); return false; } } else if (copy == keyJOB_POOL) { @@ -193,8 +203,7 @@ bool cmAddCustomCommandCommand::InitialPass( // and later references "${CMAKE_CURRENT_SOURCE_DIR}/out.txt". // This is fairly obscure so we can wait for someone to // complain. - filename = this->Makefile->GetCurrentBinaryDirectory(); - filename += "/"; + filename = cmStrCat(mf.GetCurrentBinaryDirectory(), '/'); } filename += copy; cmSystemTools::ConvertToUnixSlashes(filename); @@ -270,7 +279,7 @@ bool cmAddCustomCommandCommand::InitialPass( comment = comment_buffer.c_str(); break; default: - this->SetError("Wrong syntax. Unknown type of argument."); + status.SetError("Wrong syntax. Unknown type of argument."); return false; } } @@ -285,31 +294,31 @@ bool cmAddCustomCommandCommand::InitialPass( // At this point we could complain about the lack of arguments. For // the moment, let's say that COMMAND, TARGET are always required. if (output.empty() && target.empty()) { - this->SetError("Wrong syntax. A TARGET or OUTPUT must be specified."); + status.SetError("Wrong syntax. A TARGET or OUTPUT must be specified."); return false; } if (source.empty() && !target.empty() && !output.empty()) { - this->SetError( + status.SetError( "Wrong syntax. A TARGET and OUTPUT can not both be specified."); return false; } if (append && output.empty()) { - this->SetError("given APPEND option with no OUTPUT."); + status.SetError("given APPEND option with no OUTPUT."); return false; } // Make sure the output names and locations are safe. - if (!this->CheckOutputs(output) || !this->CheckOutputs(outputs) || - !this->CheckOutputs(byproducts)) { + if (!cmAddCustomCommandCommandCheckOutputs(output, status) || + !cmAddCustomCommandCommandCheckOutputs(outputs, status) || + !cmAddCustomCommandCommandCheckOutputs(byproducts, status)) { return false; } // Check for an append request. if (append) { // Lookup an existing command. - if (cmSourceFile* sf = - this->Makefile->GetSourceFileWithOutput(output[0])) { + if (cmSourceFile* sf = mf.GetSourceFileWithOutput(output[0])) { if (cmCustomCommand* cc = sf->GetCustomCommand()) { cc->AppendCommands(commandLines); cc->AppendDepends(depends); @@ -322,12 +331,12 @@ bool cmAddCustomCommandCommand::InitialPass( std::ostringstream e; e << "given APPEND option with output\n\"" << output[0] << "\"\nwhich is not already a custom command output."; - this->SetError(e.str()); + status.SetError(e.str()); return false; } if (uses_terminal && !job_pool.empty()) { - this->SetError("JOB_POOL is shadowed by USES_TERMINAL."); + status.SetError("JOB_POOL is shadowed by USES_TERMINAL."); return false; } @@ -336,22 +345,21 @@ bool cmAddCustomCommandCommand::InitialPass( if (source.empty() && output.empty()) { // Source is empty, use the target. std::vector<std::string> no_depends; - this->Makefile->AddCustomCommandToTarget( - target, byproducts, no_depends, commandLines, cctype, comment, - working.c_str(), escapeOldStyle, uses_terminal, depfile, job_pool, - command_expand_lists); + mf.AddCustomCommandToTarget(target, byproducts, no_depends, commandLines, + cctype, comment, working.c_str(), + escapeOldStyle, uses_terminal, depfile, + job_pool, command_expand_lists); } else if (target.empty()) { // Target is empty, use the output. - this->Makefile->AddCustomCommandToOutput( - output, byproducts, depends, main_dependency, commandLines, comment, - working.c_str(), false, escapeOldStyle, uses_terminal, - command_expand_lists, depfile, job_pool); + mf.AddCustomCommandToOutput(output, byproducts, depends, main_dependency, + commandLines, comment, working.c_str(), false, + escapeOldStyle, uses_terminal, + command_expand_lists, depfile, job_pool); // Add implicit dependency scanning requests if any were given. if (!implicit_depends.empty()) { bool okay = false; - if (cmSourceFile* sf = - this->Makefile->GetSourceFileWithOutput(output[0])) { + if (cmSourceFile* sf = mf.GetSourceFileWithOutput(output[0])) { if (cmCustomCommand* cc = sf->GetCustomCommand()) { okay = true; cc->SetImplicitDepends(implicit_depends); @@ -361,21 +369,21 @@ bool cmAddCustomCommandCommand::InitialPass( std::ostringstream e; e << "could not locate source file with a custom command producing \"" << output[0] << "\" even though this command tried to create it!"; - this->SetError(e.str()); + status.SetError(e.str()); return false; } } } else if (!byproducts.empty()) { - this->SetError("BYPRODUCTS may not be specified with SOURCE signatures"); + status.SetError("BYPRODUCTS may not be specified with SOURCE signatures"); return false; } else if (uses_terminal) { - this->SetError("USES_TERMINAL may not be used with SOURCE signatures"); + status.SetError("USES_TERMINAL may not be used with SOURCE signatures"); return false; } else { bool issueMessage = true; std::ostringstream e; MessageType messageType = MessageType::AUTHOR_WARNING; - switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0050)) { + switch (mf.GetPolicyStatus(cmPolicies::CMP0050)) { case cmPolicies::WARN: e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0050) << "\n"; break; @@ -392,30 +400,31 @@ bool cmAddCustomCommandCommand::InitialPass( if (issueMessage) { e << "The SOURCE signatures of add_custom_command are no longer " "supported."; - this->Makefile->IssueMessage(messageType, e.str()); + mf.IssueMessage(messageType, e.str()); if (messageType == MessageType::FATAL_ERROR) { return false; } } // Use the old-style mode for backward compatibility. - this->Makefile->AddCustomCommandOldStyle(target, outputs, depends, source, - commandLines, comment); + mf.AddCustomCommandOldStyle(target, outputs, depends, source, commandLines, + comment); } return true; } -bool cmAddCustomCommandCommand::CheckOutputs( - const std::vector<std::string>& outputs) +bool cmAddCustomCommandCommandCheckOutputs( + const std::vector<std::string>& outputs, cmExecutionStatus& status) { + cmMakefile& mf = status.GetMakefile(); for (std::string const& o : outputs) { // Make sure the file will not be generated into the source // directory during an out of source build. - if (!this->Makefile->CanIWriteThisFile(o)) { + if (!mf.CanIWriteThisFile(o)) { std::string e = "attempted to have a file \"" + o + "\" in a source directory as an output of custom command."; - this->SetError(e); + status.SetError(e); cmSystemTools::SetFatalErrorOccured(); return false; } @@ -426,7 +435,7 @@ bool cmAddCustomCommandCommand::CheckOutputs( std::ostringstream msg; msg << "called with OUTPUT containing a \"" << o[pos] << "\". This character is not allowed."; - this->SetError(msg.str()); + status.SetError(msg.str()); return false; } } diff --git a/Source/cmAddCustomCommandCommand.h b/Source/cmAddCustomCommandCommand.h index 6af4f10..4f8c58f 100644 --- a/Source/cmAddCustomCommandCommand.h +++ b/Source/cmAddCustomCommandCommand.h @@ -8,33 +8,9 @@ #include <string> #include <vector> -#include "cmCommand.h" - class cmExecutionStatus; -/** \class cmAddCustomCommandCommand - * \brief cmAddCustomCommandCommand defines a new command (rule) that can - * be executed within the build process - * - */ - -class cmAddCustomCommandCommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - cmCommand* Clone() override { return new cmAddCustomCommandCommand; } - - /** - * 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 CheckOutputs(const std::vector<std::string>& outputs); -}; +bool cmAddCustomCommandCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmAddCustomTargetCommand.cxx b/Source/cmAddCustomTargetCommand.cxx index 0ecd5f5..caea510 100644 --- a/Source/cmAddCustomTargetCommand.cxx +++ b/Source/cmAddCustomTargetCommand.cxx @@ -6,25 +6,25 @@ #include <utility> #include "cmCustomCommandLines.h" +#include "cmExecutionStatus.h" #include "cmGeneratorExpression.h" #include "cmGlobalGenerator.h" #include "cmMakefile.h" #include "cmMessageType.h" #include "cmStateTypes.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmTarget.h" -class cmExecutionStatus; - -// cmAddCustomTargetCommand -bool cmAddCustomTargetCommand::InitialPass( - std::vector<std::string> const& args, cmExecutionStatus&) +bool cmAddCustomTargetCommand(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; } + cmMakefile& mf = status.GetMakefile(); std::string const& targetName = args[0]; // Check the target name. @@ -33,7 +33,7 @@ bool cmAddCustomTargetCommand::InitialPass( e << "called with invalid target name \"" << targetName << "\". Target names may not contain a slash. " << "Use ADD_CUSTOM_COMMAND to generate files."; - this->SetError(e.str()); + status.SetError(e.str()); return false; } @@ -44,7 +44,8 @@ bool cmAddCustomTargetCommand::InitialPass( 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; @@ -122,8 +123,7 @@ bool cmAddCustomTargetCommand::InitialPass( case doing_byproducts: { std::string filename; if (!cmSystemTools::FileIsFullPath(copy)) { - filename = this->Makefile->GetCurrentBinaryDirectory(); - filename += "/"; + filename = cmStrCat(mf.GetCurrentBinaryDirectory(), '/'); } filename += copy; cmSystemTools::ConvertToUnixSlashes(filename); @@ -145,7 +145,7 @@ bool cmAddCustomTargetCommand::InitialPass( job_pool = copy; break; default: - this->SetError("Wrong syntax. Unknown type of argument."); + status.SetError("Wrong syntax. Unknown type of argument."); return false; } } @@ -156,7 +156,7 @@ bool cmAddCustomTargetCommand::InitialPass( std::ostringstream msg; msg << "called with target name containing a \"" << targetName[pos] << "\". This character is not allowed."; - this->SetError(msg.str()); + status.SetError(msg.str()); return false; } @@ -168,8 +168,7 @@ bool cmAddCustomTargetCommand::InitialPass( if (nameOk) { nameOk = targetName.find(':') == std::string::npos; } - if (!nameOk && - !this->Makefile->CheckCMP0037(targetName, cmStateEnums::UTILITY)) { + if (!nameOk && !mf.CheckCMP0037(targetName, cmStateEnums::UTILITY)) { return false; } @@ -182,39 +181,37 @@ bool cmAddCustomTargetCommand::InitialPass( // Enforce name uniqueness. { std::string msg; - if (!this->Makefile->EnforceUniqueName(targetName, msg, true)) { - this->SetError(msg); + if (!mf.EnforceUniqueName(targetName, msg, true)) { + status.SetError(msg); return false; } } if (commandLines.empty() && !byproducts.empty()) { - this->Makefile->IssueMessage( - MessageType::FATAL_ERROR, - "BYPRODUCTS may not be specified without any COMMAND"); + mf.IssueMessage(MessageType::FATAL_ERROR, + "BYPRODUCTS may not be specified without any COMMAND"); return true; } if (commandLines.empty() && uses_terminal) { - this->Makefile->IssueMessage( - MessageType::FATAL_ERROR, - "USES_TERMINAL may not be specified without any COMMAND"); + mf.IssueMessage(MessageType::FATAL_ERROR, + "USES_TERMINAL may not be specified without any COMMAND"); return true; } if (commandLines.empty() && command_expand_lists) { - this->Makefile->IssueMessage( + mf.IssueMessage( MessageType::FATAL_ERROR, "COMMAND_EXPAND_LISTS may not be specified without any COMMAND"); return true; } if (uses_terminal && !job_pool.empty()) { - this->SetError("JOB_POOL is shadowed by USES_TERMINAL."); + status.SetError("JOB_POOL is shadowed by USES_TERMINAL."); return false; } // Add the utility target to the makefile. bool escapeOldStyle = !verbatim; - cmTarget* target = this->Makefile->AddUtilityCommand( + cmTarget* target = mf.AddUtilityCommand( targetName, cmMakefile::TargetOrigin::Project, excludeFromAll, working_directory.c_str(), byproducts, depends, commandLines, escapeOldStyle, comment, uses_terminal, command_expand_lists, job_pool); diff --git a/Source/cmAddCustomTargetCommand.h b/Source/cmAddCustomTargetCommand.h index 1a55116..e23ef9f 100644 --- a/Source/cmAddCustomTargetCommand.h +++ b/Source/cmAddCustomTargetCommand.h @@ -8,31 +8,9 @@ #include <string> #include <vector> -#include "cmCommand.h" - class cmExecutionStatus; -/** \class cmAddCustomTargetCommand - * \brief Command that adds a target to the build system. - * - * cmAddCustomTargetCommand 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 cmAddCustomTargetCommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - cmCommand* Clone() override { return new cmAddCustomTargetCommand; } - - /** - * 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 cmAddCustomTargetCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmAddDefinitionsCommand.cxx b/Source/cmAddDefinitionsCommand.cxx index 62e57a3..0b10aee 100644 --- a/Source/cmAddDefinitionsCommand.cxx +++ b/Source/cmAddDefinitionsCommand.cxx @@ -2,21 +2,15 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmAddDefinitionsCommand.h" +#include "cmExecutionStatus.h" #include "cmMakefile.h" -class cmExecutionStatus; - -// cmAddDefinitionsCommand -bool cmAddDefinitionsCommand::InitialPass(std::vector<std::string> const& args, - cmExecutionStatus&) +bool cmAddDefinitionsCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { - // it is OK to have no arguments - if (args.empty()) { - return true; - } - + cmMakefile& mf = status.GetMakefile(); for (std::string const& i : args) { - this->Makefile->AddDefineFlag(i); + mf.AddDefineFlag(i); } return true; } diff --git a/Source/cmAddDefinitionsCommand.h b/Source/cmAddDefinitionsCommand.h index 7b75638..a67f095 100644 --- a/Source/cmAddDefinitionsCommand.h +++ b/Source/cmAddDefinitionsCommand.h @@ -8,30 +8,9 @@ #include <string> #include <vector> -#include "cmCommand.h" - class cmExecutionStatus; -/** \class cmAddDefinitionsCommand - * \brief Specify a list of compiler defines - * - * cmAddDefinitionsCommand specifies a list of compiler defines. These defines - * will be added to the compile command. - */ -class cmAddDefinitionsCommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - cmCommand* Clone() override { return new cmAddDefinitionsCommand; } - - /** - * 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 cmAddDefinitionsCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmAddDependenciesCommand.cxx b/Source/cmAddDependenciesCommand.cxx index 4956a47..0ddbda8 100644 --- a/Source/cmAddDependenciesCommand.cxx +++ b/Source/cmAddDependenciesCommand.cxx @@ -4,34 +4,33 @@ #include <sstream> +#include "cmExecutionStatus.h" #include "cmMakefile.h" #include "cmMessageType.h" #include "cmRange.h" #include "cmTarget.h" -class cmExecutionStatus; - -// cmDependenciesCommand -bool cmAddDependenciesCommand::InitialPass( - std::vector<std::string> const& args, cmExecutionStatus&) +bool cmAddDependenciesCommand(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; } + cmMakefile& mf = status.GetMakefile(); std::string const& target_name = args[0]; - if (this->Makefile->IsAlias(target_name)) { + if (mf.IsAlias(target_name)) { std::ostringstream e; e << "Cannot add target-level dependencies to alias target \"" << target_name << "\".\n"; - this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str()); + mf.IssueMessage(MessageType::FATAL_ERROR, e.str()); } - if (cmTarget* target = this->Makefile->FindTargetToUse(target_name)) { + if (cmTarget* target = mf.FindTargetToUse(target_name)) { // skip over target_name for (std::string const& arg : cmMakeRange(args).advance(1)) { - target->AddUtility(arg, this->Makefile); + target->AddUtility(arg, &mf); } } else { std::ostringstream e; @@ -41,7 +40,7 @@ bool cmAddDependenciesCommand::InitialPass( << "by the add_executable, add_library, or add_custom_target commands. " << "If you want to add file-level dependencies see the DEPENDS option " << "of the add_custom_target and add_custom_command commands."; - this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str()); + mf.IssueMessage(MessageType::FATAL_ERROR, e.str()); } return true; diff --git a/Source/cmAddDependenciesCommand.h b/Source/cmAddDependenciesCommand.h index e10df71..0c60e3a 100644 --- a/Source/cmAddDependenciesCommand.h +++ b/Source/cmAddDependenciesCommand.h @@ -8,29 +8,9 @@ #include <string> #include <vector> -#include "cmCommand.h" - class cmExecutionStatus; -/** \class cmAddDependenciesCommand - * \brief Add a dependency to a target - * - * cmAddDependenciesCommand adds a dependency to a target - */ -class cmAddDependenciesCommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - cmCommand* Clone() override { return new cmAddDependenciesCommand; } - - /** - * 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 cmAddDependenciesCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmAddExecutableCommand.cxx b/Source/cmAddExecutableCommand.cxx index 5685fdf..f1264d5 100644 --- a/Source/cmAddExecutableCommand.cxx +++ b/Source/cmAddExecutableCommand.cxx @@ -4,22 +4,22 @@ #include <sstream> +#include "cmExecutionStatus.h" #include "cmGeneratorExpression.h" #include "cmGlobalGenerator.h" #include "cmMakefile.h" #include "cmStateTypes.h" #include "cmTarget.h" -class cmExecutionStatus; - -// cmExecutableCommand -bool cmAddExecutableCommand::InitialPass(std::vector<std::string> const& args, - cmExecutionStatus&) +bool cmAddExecutableCommand(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; } + + cmMakefile& mf = status.GetMakefile(); std::vector<std::string>::const_iterator s = args.begin(); std::string const& exename = *s; @@ -61,59 +61,56 @@ bool cmAddExecutableCommand::InitialPass(std::vector<std::string> const& args, if (nameOk && !importTarget && !isAlias) { nameOk = exename.find(':') == std::string::npos; } - if (!nameOk && - !this->Makefile->CheckCMP0037(exename, cmStateEnums::EXECUTABLE)) { + if (!nameOk && !mf.CheckCMP0037(exename, cmStateEnums::EXECUTABLE)) { return false; } // Special modifiers are not allowed with IMPORTED signature. if (importTarget && (use_win32 || use_macbundle || excludeFromAll)) { if (use_win32) { - this->SetError("may not be given WIN32 for an IMPORTED target."); + status.SetError("may not be given WIN32 for an IMPORTED target."); } else if (use_macbundle) { - this->SetError("may not be given MACOSX_BUNDLE for an IMPORTED target."); + status.SetError( + "may not be given MACOSX_BUNDLE for an IMPORTED target."); } else // if(excludeFromAll) { - this->SetError( + status.SetError( "may not be given EXCLUDE_FROM_ALL for an IMPORTED target."); } return false; } if (isAlias) { if (!cmGeneratorExpression::IsValidTargetName(exename)) { - this->SetError("Invalid name for ALIAS: " + exename); + status.SetError("Invalid name for ALIAS: " + exename); return false; } if (excludeFromAll) { - this->SetError("EXCLUDE_FROM_ALL with ALIAS makes no sense."); + status.SetError("EXCLUDE_FROM_ALL with ALIAS makes no sense."); return false; } if (importTarget || importGlobal) { - this->SetError("IMPORTED with ALIAS is not allowed."); + status.SetError("IMPORTED with ALIAS is not allowed."); return false; } if (args.size() != 3) { - std::ostringstream e; - e << "ALIAS requires exactly one target argument."; - this->SetError(e.str()); + status.SetError("ALIAS requires exactly one target argument."); return false; } std::string const& aliasedName = *s; - if (this->Makefile->IsAlias(aliasedName)) { + if (mf.IsAlias(aliasedName)) { std::ostringstream e; e << "cannot create ALIAS target \"" << exename << "\" because target \"" << aliasedName << "\" is itself an ALIAS."; - this->SetError(e.str()); + status.SetError(e.str()); return false; } - cmTarget* aliasedTarget = - this->Makefile->FindTargetToUse(aliasedName, true); + cmTarget* aliasedTarget = mf.FindTargetToUse(aliasedName, true); if (!aliasedTarget) { std::ostringstream e; e << "cannot create ALIAS target \"" << exename << "\" because target \"" << aliasedName << "\" does not already exist."; - this->SetError(e.str()); + status.SetError(e.str()); return false; } cmStateEnums::TargetType type = aliasedTarget->GetType(); @@ -121,7 +118,7 @@ bool cmAddExecutableCommand::InitialPass(std::vector<std::string> const& args, std::ostringstream e; e << "cannot create ALIAS target \"" << exename << "\" because target \"" << aliasedName << "\" is not an executable."; - this->SetError(e.str()); + status.SetError(e.str()); return false; } if (aliasedTarget->IsImported() && @@ -129,42 +126,40 @@ bool cmAddExecutableCommand::InitialPass(std::vector<std::string> const& args, std::ostringstream e; e << "cannot create ALIAS target \"" << exename << "\" because target \"" << aliasedName << "\" is imported but not globally visible."; - this->SetError(e.str()); + status.SetError(e.str()); return false; } - this->Makefile->AddAlias(exename, aliasedName); + mf.AddAlias(exename, aliasedName); return true; } // Handle imported target creation. if (importTarget) { // Make sure the target does not already exist. - if (this->Makefile->FindTargetToUse(exename)) { + if (mf.FindTargetToUse(exename)) { std::ostringstream e; e << "cannot create imported target \"" << exename << "\" because another target with the same name already exists."; - this->SetError(e.str()); + status.SetError(e.str()); return false; } // Create the imported target. - this->Makefile->AddImportedTarget(exename, cmStateEnums::EXECUTABLE, - importGlobal); + mf.AddImportedTarget(exename, cmStateEnums::EXECUTABLE, importGlobal); return true; } // Enforce name uniqueness. { std::string msg; - if (!this->Makefile->EnforceUniqueName(exename, msg)) { - this->SetError(msg); + if (!mf.EnforceUniqueName(exename, msg)) { + status.SetError(msg); return false; } } std::vector<std::string> srclists(s, args.end()); - cmTarget* tgt = - this->Makefile->AddExecutable(exename, srclists, excludeFromAll); + cmTarget* tgt = mf.AddExecutable(exename, srclists, excludeFromAll); if (use_win32) { tgt->SetProperty("WIN32_EXECUTABLE", "ON"); } diff --git a/Source/cmAddExecutableCommand.h b/Source/cmAddExecutableCommand.h index bdf607d..f7bc273 100644 --- a/Source/cmAddExecutableCommand.h +++ b/Source/cmAddExecutableCommand.h @@ -8,30 +8,9 @@ #include <string> #include <vector> -#include "cmCommand.h" - class cmExecutionStatus; -/** \class cmExecutablesCommand - * \brief Defines a list of executables to build. - * - * cmExecutablesCommand defines a list of executable (i.e., test) - * programs to create. - */ -class cmAddExecutableCommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - cmCommand* Clone() override { return new cmAddExecutableCommand; } - - /** - * 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 cmAddExecutableCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmAddLibraryCommand.cxx b/Source/cmAddLibraryCommand.cxx index ad12e89..c067aea 100644 --- a/Source/cmAddLibraryCommand.cxx +++ b/Source/cmAddLibraryCommand.cxx @@ -5,30 +5,29 @@ #include <sstream> #include "cmAlgorithms.h" +#include "cmExecutionStatus.h" #include "cmGeneratorExpression.h" #include "cmGlobalGenerator.h" #include "cmMakefile.h" #include "cmMessageType.h" #include "cmState.h" #include "cmStateTypes.h" -#include "cmSystemTools.h" +#include "cmStringAlgorithms.h" #include "cmTarget.h" -class cmExecutionStatus; - -// cmLibraryCommand -bool cmAddLibraryCommand::InitialPass(std::vector<std::string> const& args, - cmExecutionStatus&) +bool cmAddLibraryCommand(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; } + + cmMakefile& mf = status.GetMakefile(); // Library type defaults to value of BUILD_SHARED_LIBS, if it exists, // otherwise it defaults to static library. cmStateEnums::TargetType type = cmStateEnums::SHARED_LIBRARY; - if (cmSystemTools::IsOff( - this->Makefile->GetDefinition("BUILD_SHARED_LIBS"))) { + if (cmIsOff(mf.GetDefinition("BUILD_SHARED_LIBS"))) { type = cmStateEnums::STATIC_LIBRARY; } bool excludeFromAll = false; @@ -50,9 +49,8 @@ bool cmAddLibraryCommand::InitialPass(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."; - this->SetError(e.str()); + status.SetError( + "INTERFACE library specified with conflicting STATIC type."); return false; } ++s; @@ -60,9 +58,8 @@ bool cmAddLibraryCommand::InitialPass(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."; - this->SetError(e.str()); + status.SetError( + "INTERFACE library specified with conflicting SHARED type."); return false; } ++s; @@ -70,9 +67,8 @@ bool cmAddLibraryCommand::InitialPass(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."; - this->SetError(e.str()); + status.SetError( + "INTERFACE library specified with conflicting MODULE type."); return false; } ++s; @@ -80,9 +76,8 @@ bool cmAddLibraryCommand::InitialPass(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."; - this->SetError(e.str()); + status.SetError( + "INTERFACE library specified with conflicting OBJECT type."); return false; } ++s; @@ -90,9 +85,8 @@ bool cmAddLibraryCommand::InitialPass(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."; - this->SetError(e.str()); + status.SetError( + "INTERFACE library specified with conflicting UNKNOWN type."); return false; } ++s; @@ -100,30 +94,26 @@ bool cmAddLibraryCommand::InitialPass(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."; - this->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."; - this->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."; - this->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."; - this->SetError(e.str()); + status.SetError( + "INTERFACE library may not be used with EXCLUDE_FROM_ALL."); return false; } ++s; @@ -131,9 +121,8 @@ bool cmAddLibraryCommand::InitialPass(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."; - this->SetError(e.str()); + status.SetError( + "INTERFACE library may not be used with EXCLUDE_FROM_ALL."); return false; } ++s; @@ -145,9 +134,8 @@ bool cmAddLibraryCommand::InitialPass(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."; - this->SetError(e.str()); + status.SetError( + "GLOBAL option may only be used with IMPORTED libraries."); return false; } else { break; @@ -156,15 +144,12 @@ bool cmAddLibraryCommand::InitialPass(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."; - this->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."; - this->SetError(e.str()); + status.SetError( + "INTERFACE library specified as GLOBAL, but not as IMPORTED."); return false; } } @@ -175,47 +160,44 @@ bool cmAddLibraryCommand::InitialPass(std::vector<std::string> const& args, if (nameOk && !importTarget && !isAlias) { nameOk = libName.find(':') == std::string::npos; } - if (!nameOk && !this->Makefile->CheckCMP0037(libName, type)) { + if (!nameOk && !mf.CheckCMP0037(libName, type)) { return false; } if (isAlias) { if (!cmGeneratorExpression::IsValidTargetName(libName)) { - this->SetError("Invalid name for ALIAS: " + libName); + status.SetError("Invalid name for ALIAS: " + libName); return false; } if (excludeFromAll) { - this->SetError("EXCLUDE_FROM_ALL with ALIAS makes no sense."); + status.SetError("EXCLUDE_FROM_ALL with ALIAS makes no sense."); return false; } if (importTarget || importGlobal) { - this->SetError("IMPORTED with ALIAS is not allowed."); + status.SetError("IMPORTED with ALIAS is not allowed."); return false; } if (args.size() != 3) { - std::ostringstream e; - e << "ALIAS requires exactly one target argument."; - this->SetError(e.str()); + status.SetError("ALIAS requires exactly one target argument."); return false; } std::string const& aliasedName = *s; - if (this->Makefile->IsAlias(aliasedName)) { + if (mf.IsAlias(aliasedName)) { std::ostringstream e; e << "cannot create ALIAS target \"" << libName << "\" because target \"" << aliasedName << "\" is itself an ALIAS."; - this->SetError(e.str()); + status.SetError(e.str()); return false; } - cmTarget* aliasedTarget = - this->Makefile->FindTargetToUse(aliasedName, true); + cmTarget* aliasedTarget = mf.FindTargetToUse(aliasedName, true); if (!aliasedTarget) { std::ostringstream e; e << "cannot create ALIAS target \"" << libName << "\" because target \"" << aliasedName << "\" does not already " "exist."; - this->SetError(e.str()); + status.SetError(e.str()); return false; } cmStateEnums::TargetType aliasedType = aliasedTarget->GetType(); @@ -229,7 +211,7 @@ bool cmAddLibraryCommand::InitialPass(std::vector<std::string> const& args, std::ostringstream e; e << "cannot create ALIAS target \"" << libName << "\" because target \"" << aliasedName << "\" is not a library."; - this->SetError(e.str()); + status.SetError(e.str()); return false; } if (aliasedTarget->IsImported() && @@ -237,15 +219,15 @@ bool cmAddLibraryCommand::InitialPass(std::vector<std::string> const& args, std::ostringstream e; e << "cannot create ALIAS target \"" << libName << "\" because target \"" << aliasedName << "\" is imported but not globally visible."; - this->SetError(e.str()); + status.SetError(e.str()); return false; } - this->Makefile->AddAlias(libName, aliasedName); + mf.AddAlias(libName, aliasedName); return true; } if (importTarget && excludeFromAll) { - this->SetError("excludeFromAll with IMPORTED target makes no sense."); + status.SetError("excludeFromAll with IMPORTED target makes no sense."); return false; } @@ -255,14 +237,13 @@ bool cmAddLibraryCommand::InitialPass(std::vector<std::string> const& args, yet its linker language. */ if ((type == cmStateEnums::SHARED_LIBRARY || type == cmStateEnums::MODULE_LIBRARY) && - !this->Makefile->GetState()->GetGlobalPropertyAsBool( - "TARGET_SUPPORTS_SHARED_LIBS")) { + !mf.GetState()->GetGlobalPropertyAsBool("TARGET_SUPPORTS_SHARED_LIBS")) { std::ostringstream w; w << "ADD_LIBRARY called with " << (type == cmStateEnums::SHARED_LIBRARY ? "SHARED" : "MODULE") << " option but the target platform does not support dynamic linking. " "Building a STATIC library instead. This may lead to problems."; - this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, w.str()); + mf.IssueMessage(MessageType::AUTHOR_WARNING, w.str()); type = cmStateEnums::STATIC_LIBRARY; } @@ -270,14 +251,13 @@ bool cmAddLibraryCommand::InitialPass(std::vector<std::string> const& args, if (importTarget) { // The IMPORTED signature requires a type to be specified explicitly. if (!haveSpecifiedType) { - this->SetError("called with IMPORTED argument but no library type."); + status.SetError("called with IMPORTED argument but no library type."); return false; } if (type == cmStateEnums::OBJECT_LIBRARY) { std::string reason; - if (!this->Makefile->GetGlobalGenerator()->HasKnownObjectFileLocation( - &reason)) { - this->Makefile->IssueMessage( + if (!mf.GetGlobalGenerator()->HasKnownObjectFileLocation(&reason)) { + mf.IssueMessage( MessageType::FATAL_ERROR, "The OBJECT library type may not be used for IMPORTED libraries" + reason + "."); @@ -288,28 +268,28 @@ bool cmAddLibraryCommand::InitialPass(std::vector<std::string> const& args, if (!cmGeneratorExpression::IsValidTargetName(libName)) { std::ostringstream e; e << "Invalid name for IMPORTED INTERFACE library target: " << libName; - this->SetError(e.str()); + status.SetError(e.str()); return false; } } // Make sure the target does not already exist. - if (this->Makefile->FindTargetToUse(libName)) { + if (mf.FindTargetToUse(libName)) { std::ostringstream e; e << "cannot create imported target \"" << libName << "\" because another target with the same name already exists."; - this->SetError(e.str()); + status.SetError(e.str()); return false; } // Create the imported target. - this->Makefile->AddImportedTarget(libName, type, importGlobal); + mf.AddImportedTarget(libName, type, importGlobal); return true; } // A non-imported target may not have UNKNOWN type. if (type == cmStateEnums::UNKNOWN_LIBRARY) { - this->Makefile->IssueMessage( + mf.IssueMessage( MessageType::FATAL_ERROR, "The UNKNOWN library type may be used only for IMPORTED libraries."); return true; @@ -318,8 +298,8 @@ bool cmAddLibraryCommand::InitialPass(std::vector<std::string> const& args, // Enforce name uniqueness. { std::string msg; - if (!this->Makefile->EnforceUniqueName(libName, msg)) { - this->SetError(msg); + if (!mf.EnforceUniqueName(libName, msg)) { + status.SetError(msg); return false; } } @@ -331,17 +311,17 @@ bool cmAddLibraryCommand::InitialPass(std::vector<std::string> const& args, libName.find("::") != std::string::npos) { std::ostringstream e; e << "Invalid name for INTERFACE library target: " << libName; - this->SetError(e.str()); + status.SetError(e.str()); return false; } - this->Makefile->AddLibrary(libName, type, srclists, excludeFromAll); + mf.AddLibrary(libName, type, srclists, excludeFromAll); return true; } cmAppend(srclists, s, args.end()); - this->Makefile->AddLibrary(libName, type, srclists, excludeFromAll); + mf.AddLibrary(libName, type, srclists, excludeFromAll); return true; } diff --git a/Source/cmAddLibraryCommand.h b/Source/cmAddLibraryCommand.h index aa21261..609449c 100644 --- a/Source/cmAddLibraryCommand.h +++ b/Source/cmAddLibraryCommand.h @@ -8,30 +8,9 @@ #include <string> #include <vector> -#include "cmCommand.h" - class cmExecutionStatus; -/** \class cmLibrarysCommand - * \brief Defines a list of executables to build. - * - * cmLibrarysCommand defines a list of executable (i.e., test) - * programs to create. - */ -class cmAddLibraryCommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - cmCommand* Clone() override { return new cmAddLibraryCommand; } - - /** - * 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 cmAddLibraryCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmAddLinkOptionsCommand.cxx b/Source/cmAddLinkOptionsCommand.cxx index 10ebd12..7ed31bd 100644 --- a/Source/cmAddLinkOptionsCommand.cxx +++ b/Source/cmAddLinkOptionsCommand.cxx @@ -2,19 +2,15 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmAddLinkOptionsCommand.h" +#include "cmExecutionStatus.h" #include "cmMakefile.h" -class cmExecutionStatus; - -bool cmAddLinkOptionsCommand::InitialPass(std::vector<std::string> const& args, - cmExecutionStatus&) +bool cmAddLinkOptionsCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { - if (args.empty()) { - return true; - } - + cmMakefile& mf = status.GetMakefile(); for (std::string const& i : args) { - this->Makefile->AddLinkOption(i); + mf.AddLinkOption(i); } return true; } diff --git a/Source/cmAddLinkOptionsCommand.h b/Source/cmAddLinkOptionsCommand.h index 30fff00..466fc32 100644 --- a/Source/cmAddLinkOptionsCommand.h +++ b/Source/cmAddLinkOptionsCommand.h @@ -8,24 +8,9 @@ #include <string> #include <vector> -#include "cmCommand.h" - class cmExecutionStatus; -class cmAddLinkOptionsCommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - cmCommand* Clone() override { return new cmAddLinkOptionsCommand; } - - /** - * 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 cmAddLinkOptionsCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmAddSubDirectoryCommand.cxx b/Source/cmAddSubDirectoryCommand.cxx index 7947188..17bdc4a 100644 --- a/Source/cmAddSubDirectoryCommand.cxx +++ b/Source/cmAddSubDirectoryCommand.cxx @@ -5,21 +5,21 @@ #include <sstream> #include <string.h> +#include "cmExecutionStatus.h" #include "cmMakefile.h" #include "cmRange.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" -class cmExecutionStatus; - -// cmAddSubDirectoryCommand -bool cmAddSubDirectoryCommand::InitialPass( - std::vector<std::string> const& args, cmExecutionStatus&) +bool cmAddSubDirectoryCommand(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; } + cmMakefile& mf = status.GetMakefile(); // store the binpath std::string const& srcArg = args.front(); std::string binArg; @@ -35,7 +35,7 @@ bool cmAddSubDirectoryCommand::InitialPass( if (binArg.empty()) { binArg = arg; } else { - this->SetError("called with incorrect number of arguments"); + status.SetError("called with incorrect number of arguments"); return false; } } @@ -46,15 +46,12 @@ bool cmAddSubDirectoryCommand::InitialPass( if (cmSystemTools::FileIsFullPath(srcArg)) { srcPath = srcArg; } else { - srcPath = this->Makefile->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."; - this->SetError(error); + std::string error = cmStrCat("given source \"", srcArg, + "\" which is not an existing directory."); + status.SetError(error); return false; } srcPath = cmSystemTools::CollapseFullPath(srcPath); @@ -65,22 +62,22 @@ bool cmAddSubDirectoryCommand::InitialPass( // No binary directory was specified. If the source directory is // not a subdirectory of the current directory then it is an // error. - if (!cmSystemTools::IsSubDirectory( - srcPath, this->Makefile->GetCurrentSourceDirectory())) { + if (!cmSystemTools::IsSubDirectory(srcPath, + mf.GetCurrentSourceDirectory())) { std::ostringstream e; e << "not given a binary directory but the given source directory " << "\"" << srcPath << "\" is not a subdirectory of \"" - << this->Makefile->GetCurrentSourceDirectory() << "\". " + << mf.GetCurrentSourceDirectory() << "\". " << "When specifying an out-of-tree source a binary directory " << "must be explicitly specified."; - this->SetError(e.str()); + status.SetError(e.str()); return false; } // Remove the CurrentDirectory from the srcPath and replace it // with the CurrentOutputDirectory. - const std::string& src = this->Makefile->GetCurrentSourceDirectory(); - const std::string& bin = this->Makefile->GetCurrentBinaryDirectory(); + const std::string& src = mf.GetCurrentSourceDirectory(); + const std::string& bin = mf.GetCurrentBinaryDirectory(); size_t srcLen = src.length(); size_t binLen = bin.length(); if (srcLen > 0 && src.back() == '/') { @@ -96,15 +93,13 @@ bool cmAddSubDirectoryCommand::InitialPass( if (cmSystemTools::FileIsFullPath(binArg)) { binPath = binArg; } else { - binPath = this->Makefile->GetCurrentBinaryDirectory(); - binPath += "/"; - binPath += binArg; + binPath = cmStrCat(mf.GetCurrentBinaryDirectory(), '/', binArg); } } binPath = cmSystemTools::CollapseFullPath(binPath); // Add the subdirectory using the computed full paths. - this->Makefile->AddSubDirectory(srcPath, binPath, excludeFromAll, true); + mf.AddSubDirectory(srcPath, binPath, excludeFromAll, true); return true; } diff --git a/Source/cmAddSubDirectoryCommand.h b/Source/cmAddSubDirectoryCommand.h index 0ea4423..87da840 100644 --- a/Source/cmAddSubDirectoryCommand.h +++ b/Source/cmAddSubDirectoryCommand.h @@ -8,31 +8,9 @@ #include <string> #include <vector> -#include "cmCommand.h" - class cmExecutionStatus; -/** \class cmAddSubDirectoryCommand - * \brief Specify a subdirectory to build - * - * cmAddSubDirectoryCommand specifies a subdirectory to process - * by CMake. CMake will descend - * into the specified source directory and process any CMakeLists.txt found. - */ -class cmAddSubDirectoryCommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - cmCommand* Clone() override { return new cmAddSubDirectoryCommand; } - - /** - * 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 cmAddSubDirectoryCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmAddTestCommand.cxx b/Source/cmAddTestCommand.cxx index bf28702..7904bf5 100644 --- a/Source/cmAddTestCommand.cxx +++ b/Source/cmAddTestCommand.cxx @@ -4,34 +4,36 @@ #include <sstream> +#include "cmExecutionStatus.h" #include "cmMakefile.h" #include "cmTest.h" #include "cmTestGenerator.h" -class cmExecutionStatus; +static bool cmAddTestCommandHandleNameMode( + std::vector<std::string> const& args, cmExecutionStatus& status); -// cmExecutableCommand -bool cmAddTestCommand::InitialPass(std::vector<std::string> const& args, - cmExecutionStatus&) +bool cmAddTestCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (!args.empty() && args[0] == "NAME") { - return this->HandleNameMode(args); + return cmAddTestCommandHandleNameMode(args, status); } // First argument is the name of the test Second argument is the name of // the executable to run (a target or external program) Remaining arguments // are the arguments to pass to the executable if (args.size() < 2) { - this->SetError("called with incorrect number of arguments"); + status.SetError("called with incorrect number of arguments"); return false; } + cmMakefile& mf = status.GetMakefile(); // Collect the command with arguments. std::vector<std::string> command(args.begin() + 1, args.end()); // Create the test but add a generator only the first time it is // seen. This preserves behavior from before test generators. - cmTest* test = this->Makefile->GetTest(args[0]); + cmTest* test = mf.GetTest(args[0]); if (test) { // If the test was already added by a new-style signature do not // allow it to be duplicated. @@ -39,25 +41,27 @@ bool cmAddTestCommand::InitialPass(std::vector<std::string> const& args, std::ostringstream e; e << " given test name \"" << args[0] << "\" which already exists in this directory."; - this->SetError(e.str()); + status.SetError(e.str()); return false; } } else { - test = this->Makefile->CreateTest(args[0]); + test = mf.CreateTest(args[0]); test->SetOldStyle(true); - this->Makefile->AddTestGenerator(new cmTestGenerator(test)); + mf.AddTestGenerator(new cmTestGenerator(test)); } test->SetCommand(command); return true; } -bool cmAddTestCommand::HandleNameMode(std::vector<std::string> const& args) +bool cmAddTestCommandHandleNameMode(std::vector<std::string> const& args, + cmExecutionStatus& status) { std::string name; std::vector<std::string> configurations; std::string working_directory; std::vector<std::string> command; + bool command_expand_lists = false; // Read the arguments. enum Doing @@ -72,22 +76,29 @@ bool cmAddTestCommand::HandleNameMode(std::vector<std::string> const& args) for (unsigned int i = 1; i < args.size(); ++i) { if (args[i] == "COMMAND") { if (!command.empty()) { - this->SetError(" may be given at most one COMMAND."); + status.SetError(" may be given at most one COMMAND."); return false; } doing = DoingCommand; } else if (args[i] == "CONFIGURATIONS") { if (!configurations.empty()) { - this->SetError(" may be given at most one set of CONFIGURATIONS."); + status.SetError(" may be given at most one set of CONFIGURATIONS."); return false; } doing = DoingConfigs; } else if (args[i] == "WORKING_DIRECTORY") { if (!working_directory.empty()) { - this->SetError(" may be given at most one WORKING_DIRECTORY."); + status.SetError(" may be given at most one WORKING_DIRECTORY."); return false; } doing = DoingWorkingDirectory; + } else if (args[i] == "COMMAND_EXPAND_LISTS") { + if (command_expand_lists) { + status.SetError(" may be given at most one COMMAND_EXPAND_LISTS."); + return false; + } + command_expand_lists = true; + doing = DoingNone; } else if (doing == DoingName) { name = args[i]; doing = DoingNone; @@ -101,40 +112,43 @@ bool cmAddTestCommand::HandleNameMode(std::vector<std::string> const& args) } else { std::ostringstream e; e << " given unknown argument:\n " << args[i] << "\n"; - this->SetError(e.str()); + status.SetError(e.str()); return false; } } // Require a test name. if (name.empty()) { - this->SetError(" must be given non-empty NAME."); + status.SetError(" must be given non-empty NAME."); return false; } // Require a command. if (command.empty()) { - this->SetError(" must be given non-empty COMMAND."); + status.SetError(" must be given non-empty COMMAND."); return false; } + cmMakefile& mf = status.GetMakefile(); + // Require a unique test name within the directory. - if (this->Makefile->GetTest(name)) { + if (mf.GetTest(name)) { std::ostringstream e; e << " given test NAME \"" << name << "\" which already exists in this directory."; - this->SetError(e.str()); + status.SetError(e.str()); return false; } // Add the test. - cmTest* test = this->Makefile->CreateTest(name); + cmTest* test = mf.CreateTest(name); test->SetOldStyle(false); test->SetCommand(command); if (!working_directory.empty()) { test->SetProperty("WORKING_DIRECTORY", working_directory.c_str()); } - this->Makefile->AddTestGenerator(new cmTestGenerator(test, configurations)); + test->SetCommandExpandLists(command_expand_lists); + mf.AddTestGenerator(new cmTestGenerator(test, configurations)); return true; } diff --git a/Source/cmAddTestCommand.h b/Source/cmAddTestCommand.h index bea3f3d..5877547 100644 --- a/Source/cmAddTestCommand.h +++ b/Source/cmAddTestCommand.h @@ -8,32 +8,9 @@ #include <string> #include <vector> -#include "cmCommand.h" - class cmExecutionStatus; -/** \class cmAddTestCommand - * \brief Add a test to the lists of tests to run. - * - * cmAddTestCommand adds a test to the list of tests to run . - */ -class cmAddTestCommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - cmCommand* Clone() override { return new cmAddTestCommand; } - - /** - * 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 HandleNameMode(std::vector<std::string> const& args); -}; +bool cmAddTestCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif 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 d1e32b0..59aa86f 100644 --- a/Source/cmAlgorithms.h +++ b/Source/cmAlgorithms.h @@ -6,93 +6,66 @@ #include "cmConfigure.h" // IWYU pragma: keep #include "cmRange.h" - #include "cm_kwiml.h" #include <algorithm> #include <functional> #include <iterator> -#include <memory> -#include <sstream> -#include <string.h> -#include <string> #include <unordered_set> #include <utility> #include <vector> -inline bool cmHasLiteralPrefixImpl(const std::string& str1, const char* str2, - size_t N) +template <std::size_t N> +struct cmOverloadPriority : cmOverloadPriority<N - 1> { - return strncmp(str1.c_str(), str2, N) == 0; -} +}; -inline bool cmHasLiteralPrefixImpl(const char* str1, const char* str2, - size_t N) +template <> +struct cmOverloadPriority<0> { - return strncmp(str1, str2, N) == 0; -} +}; -inline bool cmHasLiteralSuffixImpl(const std::string& str1, const char* str2, - size_t N) +template <typename FwdIt> +FwdIt cmRotate(FwdIt first, FwdIt middle, FwdIt last) { - size_t len = str1.size(); - return len >= N && strcmp(str1.c_str() + len - N, str2) == 0; + const typename std::iterator_traits<FwdIt>::difference_type dist = + std::distance(middle, last); + std::rotate(first, middle, last); + std::advance(first, dist); + return first; } -inline bool cmHasLiteralSuffixImpl(const char* str1, const char* str2, - size_t N) +template <typename Container, typename Predicate> +void cmEraseIf(Container& cont, Predicate pred) { - size_t len = strlen(str1); - return len >= N && strcmp(str1 + len - N, str2) == 0; + cont.erase(std::remove_if(cont.begin(), cont.end(), pred), cont.end()); } -template <typename T, size_t N> -bool cmHasLiteralPrefix(const T& str1, const char (&str2)[N]) +template <typename Range, typename Key> +auto cmContainsImpl(Range const& range, Key const& key, cmOverloadPriority<2>) + -> decltype(range.exists(key)) { - return cmHasLiteralPrefixImpl(str1, str2, N - 1); + return range.exists(key); } -template <typename T, size_t N> -bool cmHasLiteralSuffix(const T& str1, const char (&str2)[N]) +template <typename Range, typename Key> +auto cmContainsImpl(Range const& range, Key const& key, cmOverloadPriority<1>) + -> decltype(range.find(key) != range.end()) { - return cmHasLiteralSuffixImpl(str1, str2, N - 1); + return range.find(key) != range.end(); } -struct cmStrCmp +template <typename Range, typename Key> +bool cmContainsImpl(Range const& range, Key const& key, cmOverloadPriority<0>) { - cmStrCmp(const char* test) - : m_test(test) - { - } - cmStrCmp(std::string test) - : m_test(std::move(test)) - { - } - - bool operator()(const std::string& input) const { return m_test == input; } - - bool operator()(const char* input) const - { - return strcmp(input, m_test.c_str()) == 0; - } - -private: - const std::string m_test; -}; - -template <typename FwdIt> -FwdIt cmRotate(FwdIt first, FwdIt middle, FwdIt last) -{ - const typename std::iterator_traits<FwdIt>::difference_type dist = - std::distance(middle, last); - std::rotate(first, middle, last); - std::advance(first, dist); - return first; + using std::begin; + using std::end; + return std::find(begin(range), end(range), key) != end(range); } -template <typename Container, typename Predicate> -void cmEraseIf(Container& cont, Predicate pred) +template <typename Range, typename Key> +bool cmContains(Range const& range, Key const& key) { - cont.erase(std::remove_if(cont.begin(), cont.end(), pred), cont.end()); + return cmContainsImpl(range, key, cmOverloadPriority<2>{}); } namespace ContainerAlgorithms { @@ -158,8 +131,6 @@ private: }; } -typedef cmRange<std::vector<std::string>::const_iterator> cmStringRange; - class cmListFileBacktrace; typedef cmRange<std::vector<cmListFileBacktrace>::const_iterator> cmBacktraceRange; @@ -184,31 +155,6 @@ void cmAppend(std::vector<T>& v, InputIt first, InputIt last) } template <typename Range> -std::string cmJoin(Range const& r, const char* delimiter) -{ - if (r.empty()) { - return std::string(); - } - std::ostringstream os; - typedef typename Range::value_type ValueType; - typedef typename Range::const_iterator InputIt; - const InputIt first = r.begin(); - InputIt last = r.end(); - --last; - std::copy(first, last, std::ostream_iterator<ValueType>(os, delimiter)); - - os << *last; - - return os.str(); -} - -template <typename Range> -std::string cmJoin(Range const& r, std::string const& delimiter) -{ - return cmJoin(r, delimiter.c_str()); -} - -template <typename Range> typename Range::const_iterator cmRemoveN(Range& r, size_t n) { return ContainerAlgorithms::RemoveN(r.begin(), r.end(), n); @@ -268,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); } @@ -286,23 +232,6 @@ typename Range::const_iterator cmRemoveDuplicates(Range& r) return cmRemoveDuplicates(r.begin(), r.end()); } -template <typename Range> -std::string cmWrap(std::string const& prefix, Range const& r, - std::string const& suffix, std::string const& sep) -{ - if (r.empty()) { - return std::string(); - } - return prefix + cmJoin(r, suffix + sep + prefix) + suffix; -} - -template <typename Range> -std::string cmWrap(char prefix, Range const& r, char suffix, - std::string const& sep) -{ - return cmWrap(std::string(1, prefix), r, std::string(1, suffix), sep); -} - template <typename Range, typename T> typename Range::const_iterator cmFindNot(Range const& r, T const& t) { @@ -315,45 +244,8 @@ std::reverse_iterator<Iter> cmMakeReverseIterator(Iter it) return std::reverse_iterator<Iter>(it); } -inline bool cmHasPrefix(std::string const& str, std::string const& prefix) -{ - if (str.size() < prefix.size()) { - return false; - } - return str.compare(0, prefix.size(), prefix) == 0; -} - -inline bool cmHasSuffix(const std::string& str, const std::string& suffix) -{ - if (str.size() < suffix.size()) { - return false; - } - return str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0; -} - -inline void cmStripSuffixIfExists(std::string& str, const std::string& suffix) -{ - if (cmHasSuffix(str, suffix)) { - str.resize(str.size() - suffix.size()); - } -} - namespace cm { -#if defined(CMake_HAVE_CXX_MAKE_UNIQUE) - -using std::make_unique; - -#else - -template <typename T, typename... Args> -std::unique_ptr<T> make_unique(Args&&... args) -{ - return std::unique_ptr<T>(new T(std::forward<Args>(args)...)); -} - -#endif - #if __cplusplus >= 201703L || defined(_MSVC_LANG) && _MSVC_LANG >= 201703L using std::size; 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/cmArchiveWrite.h b/Source/cmArchiveWrite.h index 9ea88d3..e90a603 100644 --- a/Source/cmArchiveWrite.h +++ b/Source/cmArchiveWrite.h @@ -9,7 +9,7 @@ #include <stddef.h> #include <string> -#if !defined(CMAKE_BUILD_WITH_CMAKE) +#if defined(CMAKE_BOOTSTRAP) # error "cmArchiveWrite not allowed during bootstrap build!" #endif diff --git a/Source/cmAuxSourceDirectoryCommand.cxx b/Source/cmAuxSourceDirectoryCommand.cxx index 106e7a7..7bf19d0 100644 --- a/Source/cmAuxSourceDirectoryCommand.cxx +++ b/Source/cmAuxSourceDirectoryCommand.cxx @@ -7,36 +7,33 @@ #include <stddef.h> #include <utility> -#include "cmAlgorithms.h" +#include "cmExecutionStatus.h" #include "cmMakefile.h" #include "cmSourceFile.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmake.h" -class cmExecutionStatus; - -// cmAuxSourceDirectoryCommand -bool cmAuxSourceDirectoryCommand::InitialPass( - std::vector<std::string> const& args, cmExecutionStatus&) +bool cmAuxSourceDirectoryCommand(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; } + cmMakefile& mf = status.GetMakefile(); std::string sourceListValue; std::string const& templateDirectory = args[0]; std::string tdir; if (!cmSystemTools::FileIsFullPath(templateDirectory)) { - tdir = this->Makefile->GetCurrentSourceDirectory(); - tdir += "/"; - tdir += templateDirectory; + tdir = cmStrCat(mf.GetCurrentSourceDirectory(), '/', templateDirectory); } else { tdir = templateDirectory; } // was the list already populated - const char* def = this->Makefile->GetDefinition(args[1]); + const char* def = mf.GetDefinition(args[1]); if (def) { sourceListValue = def; } @@ -55,14 +52,12 @@ bool cmAuxSourceDirectoryCommand::InitialPass( std::string ext = file.substr(dotpos + 1); std::string base = file.substr(0, dotpos); // Process only source files - auto cm = this->Makefile->GetCMakeInstance(); + 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 = this->Makefile->GetOrCreateSource(fullname); + cmSourceFile* sf = mf.GetOrCreateSource(fullname); sf->SetProperty("ABSTRACT", "0"); files.push_back(std::move(fullname)); } @@ -74,6 +69,6 @@ bool cmAuxSourceDirectoryCommand::InitialPass( sourceListValue += ";"; } sourceListValue += cmJoin(files, ";"); - this->Makefile->AddDefinition(args[1], sourceListValue.c_str()); + mf.AddDefinition(args[1], sourceListValue); return true; } diff --git a/Source/cmAuxSourceDirectoryCommand.h b/Source/cmAuxSourceDirectoryCommand.h index 3742e3e..ae26092 100644 --- a/Source/cmAuxSourceDirectoryCommand.h +++ b/Source/cmAuxSourceDirectoryCommand.h @@ -8,33 +8,9 @@ #include <string> #include <vector> -#include "cmCommand.h" - class cmExecutionStatus; -/** \class cmAuxSourceDirectoryCommand - * \brief Specify auxiliary source code directories. - * - * cmAuxSourceDirectoryCommand specifies source code directories - * that must be built as part of this build process. This directories - * are not recursively processed like the SUBDIR command (cmSubdirCommand). - * A side effect of this command is to create a subdirectory in the build - * directory structure. - */ -class cmAuxSourceDirectoryCommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - cmCommand* Clone() override { return new cmAuxSourceDirectoryCommand; } - - /** - * 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 cmAuxSourceDirectoryCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmBinUtilsLinker.cxx b/Source/cmBinUtilsLinker.cxx new file mode 100644 index 0000000..3dac85c --- /dev/null +++ b/Source/cmBinUtilsLinker.cxx @@ -0,0 +1,15 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ + +#include "cmBinUtilsLinker.h" +#include "cmRuntimeDependencyArchive.h" + +cmBinUtilsLinker::cmBinUtilsLinker(cmRuntimeDependencyArchive* archive) + : Archive(archive) +{ +} + +void cmBinUtilsLinker::SetError(const std::string& e) +{ + this->Archive->SetError(e); +} diff --git a/Source/cmBinUtilsLinker.h b/Source/cmBinUtilsLinker.h new file mode 100644 index 0000000..29853a5 --- /dev/null +++ b/Source/cmBinUtilsLinker.h @@ -0,0 +1,30 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ + +#ifndef cmBinUtilsLinker_h +#define cmBinUtilsLinker_h + +#include "cmStateTypes.h" + +#include <string> + +class cmRuntimeDependencyArchive; + +class cmBinUtilsLinker +{ +public: + cmBinUtilsLinker(cmRuntimeDependencyArchive* archive); + virtual ~cmBinUtilsLinker() = default; + + virtual bool Prepare() { return true; } + + virtual bool ScanDependencies(std::string const& file, + cmStateEnums::TargetType type) = 0; + +protected: + cmRuntimeDependencyArchive* Archive; + + void SetError(const std::string& e); +}; + +#endif // cmBinUtilsLinker_h diff --git a/Source/cmBinUtilsLinuxELFGetRuntimeDependenciesTool.cxx b/Source/cmBinUtilsLinuxELFGetRuntimeDependenciesTool.cxx new file mode 100644 index 0000000..40de592 --- /dev/null +++ b/Source/cmBinUtilsLinuxELFGetRuntimeDependenciesTool.cxx @@ -0,0 +1,18 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ + +#include "cmBinUtilsLinuxELFGetRuntimeDependenciesTool.h" +#include "cmRuntimeDependencyArchive.h" + +cmBinUtilsLinuxELFGetRuntimeDependenciesTool:: + cmBinUtilsLinuxELFGetRuntimeDependenciesTool( + cmRuntimeDependencyArchive* archive) + : Archive(archive) +{ +} + +void cmBinUtilsLinuxELFGetRuntimeDependenciesTool::SetError( + const std::string& error) +{ + this->Archive->SetError(error); +} diff --git a/Source/cmBinUtilsLinuxELFGetRuntimeDependenciesTool.h b/Source/cmBinUtilsLinuxELFGetRuntimeDependenciesTool.h new file mode 100644 index 0000000..d514e7f --- /dev/null +++ b/Source/cmBinUtilsLinuxELFGetRuntimeDependenciesTool.h @@ -0,0 +1,30 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ + +#ifndef cmBinUtilsLinuxELFGetRuntimeDependenciesTool_h +#define cmBinUtilsLinuxELFGetRuntimeDependenciesTool_h + +#include <string> +#include <vector> + +class cmRuntimeDependencyArchive; + +class cmBinUtilsLinuxELFGetRuntimeDependenciesTool +{ +public: + cmBinUtilsLinuxELFGetRuntimeDependenciesTool( + cmRuntimeDependencyArchive* archive); + virtual ~cmBinUtilsLinuxELFGetRuntimeDependenciesTool() = default; + + virtual bool GetFileInfo(std::string const& file, + std::vector<std::string>& needed, + std::vector<std::string>& rpaths, + std::vector<std::string>& runpaths) = 0; + +protected: + cmRuntimeDependencyArchive* Archive; + + void SetError(const std::string& e); +}; + +#endif // cmBinUtilsLinuxELFGetRuntimeDependenciesTool_h diff --git a/Source/cmBinUtilsLinuxELFLinker.cxx b/Source/cmBinUtilsLinuxELFLinker.cxx new file mode 100644 index 0000000..6316a29 --- /dev/null +++ b/Source/cmBinUtilsLinuxELFLinker.cxx @@ -0,0 +1,179 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ + +#include "cmBinUtilsLinuxELFLinker.h" + +#include "cmBinUtilsLinuxELFObjdumpGetRuntimeDependenciesTool.h" +#include "cmLDConfigLDConfigTool.h" +#include "cmMakefile.h" +#include "cmMessageType.h" +#include "cmRuntimeDependencyArchive.h" +#include "cmStringAlgorithms.h" +#include "cmSystemTools.h" + +#include <cmsys/RegularExpression.hxx> + +#include <sstream> + +#include "cm_memory.hxx" + +static std::string ReplaceOrigin(const std::string& rpath, + const std::string& origin) +{ + static const cmsys::RegularExpression originRegex( + "(\\$ORIGIN)([^a-zA-Z0-9_]|$)"); + static const cmsys::RegularExpression originCurlyRegex("\\${ORIGIN}"); + + cmsys::RegularExpressionMatch match; + if (originRegex.find(rpath.c_str(), match)) { + std::string begin = rpath.substr(0, match.start(1)); + std::string end = rpath.substr(match.end(1)); + return begin + origin + end; + } + if (originCurlyRegex.find(rpath.c_str(), match)) { + std::string begin = rpath.substr(0, match.start()); + std::string end = rpath.substr(match.end()); + return begin + origin + end; + } + return rpath; +} + +cmBinUtilsLinuxELFLinker::cmBinUtilsLinuxELFLinker( + cmRuntimeDependencyArchive* archive) + : cmBinUtilsLinker(archive) +{ +} + +bool cmBinUtilsLinuxELFLinker::Prepare() +{ + std::string tool = this->Archive->GetGetRuntimeDependenciesTool(); + if (tool.empty()) { + tool = "objdump"; + } + if (tool == "objdump") { + this->Tool = + cm::make_unique<cmBinUtilsLinuxELFObjdumpGetRuntimeDependenciesTool>( + this->Archive); + } else { + std::ostringstream e; + e << "Invalid value for CMAKE_GET_RUNTIME_DEPENDENCIES_TOOL: " << tool; + this->SetError(e.str()); + return false; + } + + std::string ldConfigTool = + this->Archive->GetMakefile()->GetSafeDefinition("CMAKE_LDCONFIG_TOOL"); + if (ldConfigTool.empty()) { + ldConfigTool = "ldconfig"; + } + if (ldConfigTool == "ldconfig") { + this->LDConfigTool = + cm::make_unique<cmLDConfigLDConfigTool>(this->Archive); + } else { + std::ostringstream e; + e << "Invalid value for CMAKE_LDCONFIG_TOOL: " << ldConfigTool; + this->SetError(e.str()); + return false; + } + + return true; +} + +bool cmBinUtilsLinuxELFLinker::ScanDependencies( + std::string const& file, cmStateEnums::TargetType /* unused */) +{ + std::vector<std::string> parentRpaths; + return this->ScanDependencies(file, parentRpaths); +} + +bool cmBinUtilsLinuxELFLinker::ScanDependencies( + std::string const& file, std::vector<std::string> const& parentRpaths) +{ + std::string origin = cmSystemTools::GetFilenamePath(file); + std::vector<std::string> needed; + std::vector<std::string> rpaths; + std::vector<std::string> runpaths; + if (!this->Tool->GetFileInfo(file, needed, rpaths, runpaths)) { + return false; + } + for (auto& runpath : runpaths) { + runpath = ReplaceOrigin(runpath, origin); + } + for (auto& rpath : rpaths) { + rpath = ReplaceOrigin(rpath, origin); + } + + std::vector<std::string> searchPaths; + if (!runpaths.empty()) { + searchPaths = runpaths; + } else { + searchPaths = rpaths; + searchPaths.insert(searchPaths.end(), parentRpaths.begin(), + parentRpaths.end()); + } + + std::vector<std::string> ldConfigPaths; + if (!this->LDConfigTool->GetLDConfigPaths(ldConfigPaths)) { + return false; + } + searchPaths.insert(searchPaths.end(), ldConfigPaths.begin(), + ldConfigPaths.end()); + + for (auto const& dep : needed) { + if (!this->Archive->IsPreExcluded(dep)) { + std::string path; + bool resolved = false; + if (dep.find('/') != std::string::npos) { + this->SetError("Paths to dependencies are not supported"); + return false; + } + if (!this->ResolveDependency(dep, searchPaths, path, resolved)) { + return false; + } + if (resolved) { + if (!this->Archive->IsPostExcluded(path)) { + bool unique; + this->Archive->AddResolvedPath(dep, path, unique); + if (unique && !this->ScanDependencies(path, rpaths)) { + return false; + } + } + } else { + this->Archive->AddUnresolvedPath(dep); + } + } + } + + return true; +} + +bool cmBinUtilsLinuxELFLinker::ResolveDependency( + std::string const& name, std::vector<std::string> const& searchPaths, + std::string& path, bool& resolved) +{ + for (auto const& searchPath : searchPaths) { + path = cmStrCat(searchPath, '/', name); + if (cmSystemTools::PathExists(path)) { + resolved = true; + return true; + } + } + + for (auto const& searchPath : this->Archive->GetSearchDirectories()) { + path = cmStrCat(searchPath, '/', name); + if (cmSystemTools::PathExists(path)) { + std::ostringstream warning; + warning << "Dependency " << name << " found in search directory:\n " + << searchPath + << "\nSee file(GET_RUNTIME_DEPENDENCIES) documentation for " + << "more information."; + this->Archive->GetMakefile()->IssueMessage(MessageType::WARNING, + warning.str()); + resolved = true; + return true; + } + } + + resolved = false; + return true; +} diff --git a/Source/cmBinUtilsLinuxELFLinker.h b/Source/cmBinUtilsLinuxELFLinker.h new file mode 100644 index 0000000..e209637 --- /dev/null +++ b/Source/cmBinUtilsLinuxELFLinker.h @@ -0,0 +1,44 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ + +#ifndef cmBinUtilsLinuxELFLinker_h +#define cmBinUtilsLinuxELFLinker_h + +#include "cmBinUtilsLinker.h" +#include "cmBinUtilsLinuxELFGetRuntimeDependenciesTool.h" +#include "cmLDConfigTool.h" +#include "cmStateTypes.h" + +#include <memory> +#include <string> +#include <vector> + +class cmRuntimeDependencyArchive; + +class cmBinUtilsLinuxELFLinker : public cmBinUtilsLinker +{ +public: + cmBinUtilsLinuxELFLinker(cmRuntimeDependencyArchive* archive); + + bool Prepare() override; + + bool ScanDependencies(std::string const& file, + cmStateEnums::TargetType type) override; + +private: + std::unique_ptr<cmBinUtilsLinuxELFGetRuntimeDependenciesTool> Tool; + std::unique_ptr<cmLDConfigTool> LDConfigTool; + bool HaveLDConfigPaths = false; + std::vector<std::string> LDConfigPaths; + + bool ScanDependencies(std::string const& file, + std::vector<std::string> const& parentRpaths); + + bool ResolveDependency(std::string const& name, + std::vector<std::string> const& searchPaths, + std::string& path, bool& resolved); + + bool GetLDConfigPaths(); +}; + +#endif // cmBinUtilsLinuxELFLinker_h diff --git a/Source/cmBinUtilsLinuxELFObjdumpGetRuntimeDependenciesTool.cxx b/Source/cmBinUtilsLinuxELFObjdumpGetRuntimeDependenciesTool.cxx new file mode 100644 index 0000000..3bf7bf8 --- /dev/null +++ b/Source/cmBinUtilsLinuxELFObjdumpGetRuntimeDependenciesTool.cxx @@ -0,0 +1,84 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ + +#include "cmBinUtilsLinuxELFObjdumpGetRuntimeDependenciesTool.h" +#include "cmRuntimeDependencyArchive.h" +#include "cmSystemTools.h" +#include "cmUVProcessChain.h" + +#include <cmsys/RegularExpression.hxx> + +#include <sstream> + +cmBinUtilsLinuxELFObjdumpGetRuntimeDependenciesTool:: + cmBinUtilsLinuxELFObjdumpGetRuntimeDependenciesTool( + cmRuntimeDependencyArchive* archive) + : cmBinUtilsLinuxELFGetRuntimeDependenciesTool(archive) +{ +} + +bool cmBinUtilsLinuxELFObjdumpGetRuntimeDependenciesTool::GetFileInfo( + std::string const& file, std::vector<std::string>& needed, + std::vector<std::string>& rpaths, std::vector<std::string>& runpaths) +{ + cmUVProcessChainBuilder builder; + builder.SetBuiltinStream(cmUVProcessChainBuilder::Stream_OUTPUT); + + std::vector<std::string> command; + if (!this->Archive->GetGetRuntimeDependenciesCommand("objdump", command)) { + this->SetError("Could not find objdump"); + return false; + } + command.emplace_back("-p"); + command.push_back(file); + builder.AddCommand(command); + + auto process = builder.Start(); + if (!process.Valid()) { + std::ostringstream e; + e << "Failed to start objdump process for:\n " << file; + this->SetError(e.str()); + return false; + } + + std::string line; + static const cmsys::RegularExpression neededRegex("^ *NEEDED *([^\n]*)$"); + static const cmsys::RegularExpression rpathRegex("^ *RPATH *([^\n]*)$"); + static const cmsys::RegularExpression runpathRegex("^ *RUNPATH *([^\n]*)$"); + while (std::getline(*process.OutputStream(), line)) { + cmsys::RegularExpressionMatch match; + if (neededRegex.find(line.c_str(), match)) { + needed.push_back(match.match(1)); + } else if (rpathRegex.find(line.c_str(), match)) { + std::vector<std::string> rpathSplit = + cmSystemTools::SplitString(match.match(1), ':'); + rpaths.reserve(rpaths.size() + rpathSplit.size()); + for (auto const& rpath : rpathSplit) { + rpaths.push_back(rpath); + } + } else if (runpathRegex.find(line.c_str(), match)) { + std::vector<std::string> runpathSplit = + cmSystemTools::SplitString(match.match(1), ':'); + runpaths.reserve(runpaths.size() + runpathSplit.size()); + for (auto const& runpath : runpathSplit) { + runpaths.push_back(runpath); + } + } + } + + if (!process.Wait()) { + std::ostringstream e; + e << "Failed to wait on objdump process for:\n " << file; + this->SetError(e.str()); + return false; + } + auto status = process.GetStatus(); + if (!status[0] || status[0]->ExitStatus != 0) { + std::ostringstream e; + e << "Failed to run objdump on:\n " << file; + this->SetError(e.str()); + return false; + } + + return true; +} diff --git a/Source/cmBinUtilsLinuxELFObjdumpGetRuntimeDependenciesTool.h b/Source/cmBinUtilsLinuxELFObjdumpGetRuntimeDependenciesTool.h new file mode 100644 index 0000000..286337f --- /dev/null +++ b/Source/cmBinUtilsLinuxELFObjdumpGetRuntimeDependenciesTool.h @@ -0,0 +1,26 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ + +#ifndef cmBinUtilsLinuxELFGetRuntimeCollectDependenciesTool_h +#define cmBinUtilsLinuxELFGetRuntimeCollectDependenciesTool_h + +#include "cmBinUtilsLinuxELFGetRuntimeDependenciesTool.h" + +#include <string> +#include <vector> + +class cmRuntimeDependencyArchive; + +class cmBinUtilsLinuxELFObjdumpGetRuntimeDependenciesTool + : public cmBinUtilsLinuxELFGetRuntimeDependenciesTool +{ +public: + cmBinUtilsLinuxELFObjdumpGetRuntimeDependenciesTool( + cmRuntimeDependencyArchive* archive); + + bool GetFileInfo(std::string const& file, std::vector<std::string>& needed, + std::vector<std::string>& rpaths, + std::vector<std::string>& runpaths) override; +}; + +#endif // cmBinUtilsLinuxELFObjdumpGetRuntimeDependenciesTool_h diff --git a/Source/cmBinUtilsMacOSMachOGetRuntimeDependenciesTool.cxx b/Source/cmBinUtilsMacOSMachOGetRuntimeDependenciesTool.cxx new file mode 100644 index 0000000..a296a47 --- /dev/null +++ b/Source/cmBinUtilsMacOSMachOGetRuntimeDependenciesTool.cxx @@ -0,0 +1,19 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ + +#include "cmBinUtilsMacOSMachOGetRuntimeDependenciesTool.h" + +#include "cmRuntimeDependencyArchive.h" + +cmBinUtilsMacOSMachOGetRuntimeDependenciesTool:: + cmBinUtilsMacOSMachOGetRuntimeDependenciesTool( + cmRuntimeDependencyArchive* archive) + : Archive(archive) +{ +} + +void cmBinUtilsMacOSMachOGetRuntimeDependenciesTool::SetError( + const std::string& error) +{ + this->Archive->SetError(error); +} diff --git a/Source/cmBinUtilsMacOSMachOGetRuntimeDependenciesTool.h b/Source/cmBinUtilsMacOSMachOGetRuntimeDependenciesTool.h new file mode 100644 index 0000000..dbb2882 --- /dev/null +++ b/Source/cmBinUtilsMacOSMachOGetRuntimeDependenciesTool.h @@ -0,0 +1,29 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ + +#ifndef cmBinUtilsMacOSMachOGetRuntimeDependenciesTool_h +#define cmBinUtilsMacOSMachOGetRuntimeDependenciesTool_h + +#include <string> +#include <vector> + +class cmRuntimeDependencyArchive; + +class cmBinUtilsMacOSMachOGetRuntimeDependenciesTool +{ +public: + cmBinUtilsMacOSMachOGetRuntimeDependenciesTool( + cmRuntimeDependencyArchive* archive); + virtual ~cmBinUtilsMacOSMachOGetRuntimeDependenciesTool() = default; + + virtual bool GetFileInfo(std::string const& file, + std::vector<std::string>& libs, + std::vector<std::string>& rpaths) = 0; + +protected: + cmRuntimeDependencyArchive* Archive; + + void SetError(const std::string& error); +}; + +#endif // cmBinUtilsMacOSMachOGetRuntimeDependenciesTool_h diff --git a/Source/cmBinUtilsMacOSMachOLinker.cxx b/Source/cmBinUtilsMacOSMachOLinker.cxx new file mode 100644 index 0000000..7ff8584 --- /dev/null +++ b/Source/cmBinUtilsMacOSMachOLinker.cxx @@ -0,0 +1,231 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ + +#include "cmBinUtilsMacOSMachOLinker.h" + +#include "cmBinUtilsMacOSMachOOToolGetRuntimeDependenciesTool.h" +#include "cmRuntimeDependencyArchive.h" +#include "cmStringAlgorithms.h" +#include "cmSystemTools.h" + +#include <sstream> +#include <string> +#include <vector> + +#include "cm_memory.hxx" + +cmBinUtilsMacOSMachOLinker::cmBinUtilsMacOSMachOLinker( + cmRuntimeDependencyArchive* archive) + : cmBinUtilsLinker(archive) +{ +} + +bool cmBinUtilsMacOSMachOLinker::Prepare() +{ + std::string tool = this->Archive->GetGetRuntimeDependenciesTool(); + if (tool.empty()) { + tool = "otool"; + } + if (tool == "otool") { + this->Tool = + cm::make_unique<cmBinUtilsMacOSMachOOToolGetRuntimeDependenciesTool>( + this->Archive); + } else { + std::ostringstream e; + e << "Invalid value for CMAKE_GET_RUNTIME_DEPENDENCIES_TOOL: " << tool; + this->SetError(e.str()); + return false; + } + + return true; +} + +bool cmBinUtilsMacOSMachOLinker::ScanDependencies( + std::string const& file, cmStateEnums::TargetType type) +{ + std::string executableFile; + if (type == cmStateEnums::EXECUTABLE) { + executableFile = file; + } else { + executableFile = this->Archive->GetBundleExecutable(); + } + std::string executablePath; + if (!executableFile.empty()) { + executablePath = cmSystemTools::GetFilenamePath(executableFile); + } + return this->ScanDependencies(file, executablePath); +} + +bool cmBinUtilsMacOSMachOLinker::ScanDependencies( + std::string const& file, std::string const& executablePath) +{ + std::vector<std::string> libs; + std::vector<std::string> rpaths; + if (!this->Tool->GetFileInfo(file, libs, rpaths)) { + return false; + } + + std::string loaderPath = cmSystemTools::GetFilenamePath(file); + return this->GetFileDependencies(libs, executablePath, loaderPath, rpaths); +} + +bool cmBinUtilsMacOSMachOLinker::GetFileDependencies( + std::vector<std::string> const& names, std::string const& executablePath, + std::string const& loaderPath, std::vector<std::string> const& rpaths) +{ + for (std::string const& name : names) { + if (!this->Archive->IsPreExcluded(name)) { + std::string path; + bool resolved; + if (!this->ResolveDependency(name, executablePath, loaderPath, rpaths, + path, resolved)) { + return false; + } + if (resolved) { + if (!this->Archive->IsPostExcluded(path)) { + auto filename = cmSystemTools::GetFilenameName(path); + bool unique; + this->Archive->AddResolvedPath(filename, path, unique); + if (unique && !this->ScanDependencies(path, executablePath)) { + return false; + } + } + } else { + this->Archive->AddUnresolvedPath(name); + } + } + } + + return true; +} + +bool cmBinUtilsMacOSMachOLinker::ResolveDependency( + std::string const& name, std::string const& executablePath, + std::string const& loaderPath, std::vector<std::string> const& rpaths, + std::string& path, bool& resolved) +{ + resolved = false; + if (cmHasLiteralPrefix(name, "@rpath/")) { + if (!this->ResolveRPathDependency(name, executablePath, loaderPath, rpaths, + path, resolved)) { + return false; + } + } else if (cmHasLiteralPrefix(name, "@loader_path/")) { + if (!this->ResolveLoaderPathDependency(name, loaderPath, path, resolved)) { + return false; + } + } else if (cmHasLiteralPrefix(name, "@executable_path/")) { + if (!this->ResolveExecutablePathDependency(name, executablePath, path, + resolved)) { + return false; + } + } else { + resolved = true; + path = name; + } + + if (resolved && !cmSystemTools::FileIsFullPath(path)) { + this->SetError("Resolved path is not absolute"); + return false; + } + + return true; +} + +bool cmBinUtilsMacOSMachOLinker::ResolveExecutablePathDependency( + std::string const& name, std::string const& executablePath, + std::string& path, bool& resolved) +{ + if (executablePath.empty()) { + resolved = false; + return true; + } + + // 16 is == "@executable_path".length() + path = name; + path.replace(0, 16, executablePath); + + if (!cmSystemTools::PathExists(path)) { + resolved = false; + return true; + } + + resolved = true; + return true; +} + +bool cmBinUtilsMacOSMachOLinker::ResolveLoaderPathDependency( + std::string const& name, std::string const& loaderPath, std::string& path, + bool& resolved) +{ + if (loaderPath.empty()) { + resolved = false; + return true; + } + + // 12 is "@loader_path".length(); + path = name; + path.replace(0, 12, loaderPath); + + if (!cmSystemTools::PathExists(path)) { + resolved = false; + return true; + } + + resolved = true; + return true; +} + +bool cmBinUtilsMacOSMachOLinker::ResolveRPathDependency( + std::string const& name, std::string const& executablePath, + std::string const& loaderPath, std::vector<std::string> const& rpaths, + std::string& path, bool& resolved) +{ + for (std::string const& rpath : rpaths) { + std::string searchFile = name; + searchFile.replace(0, 6, rpath); + if (cmHasLiteralPrefix(searchFile, "@loader_path/")) { + if (!this->ResolveLoaderPathDependency(searchFile, loaderPath, path, + resolved)) { + return false; + } + if (resolved) { + return true; + } + } else if (cmHasLiteralPrefix(searchFile, "@executable_path/")) { + if (!this->ResolveExecutablePathDependency(searchFile, executablePath, + path, resolved)) { + return false; + } + if (resolved) { + return true; + } + } else if (cmSystemTools::PathExists(searchFile)) { + /* + * paraphrasing @ben.boeckel: + * if /b/libB.dylib is supposed to be used, + * /a/libbB.dylib will be found first if it exists. CMake tries to + * sort rpath directories to avoid this, but sometimes there is no + * right answer. + * + * I believe it is possible to resolve this using otools -l + * then checking the LC_LOAD_DYLIB command whose name is + * equal to the value of search_file, UNLESS the build + * specifically sets the RPath to paths that will match + * duplicate libs; at this point can we just point to + * user error, or is there a reason why the advantages + * to this scenario outweigh its disadvantages? + * + * Also priority seems to be the order as passed in when compiled + * so as long as this method's resolution guarantees priority + * in that manner further checking should not be necessary? + */ + path = searchFile; + resolved = true; + return true; + } + } + + resolved = false; + return true; +} diff --git a/Source/cmBinUtilsMacOSMachOLinker.h b/Source/cmBinUtilsMacOSMachOLinker.h new file mode 100644 index 0000000..f4f309d --- /dev/null +++ b/Source/cmBinUtilsMacOSMachOLinker.h @@ -0,0 +1,59 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ + +#ifndef cmBinUtilsMacOSMachOLinker_h +#define cmBinUtilsMacOSMachOLinker_h + +#include "cmBinUtilsLinker.h" +#include "cmBinUtilsMacOSMachOGetRuntimeDependenciesTool.h" +#include "cmStateTypes.h" + +#include <memory> +#include <string> +#include <vector> + +class cmRuntimeDependencyArchive; + +class cmBinUtilsMacOSMachOLinker : public cmBinUtilsLinker +{ +public: + cmBinUtilsMacOSMachOLinker(cmRuntimeDependencyArchive* archive); + + bool Prepare() override; + + bool ScanDependencies(std::string const& file, + cmStateEnums::TargetType type) override; + +private: + std::unique_ptr<cmBinUtilsMacOSMachOGetRuntimeDependenciesTool> Tool; + + bool ScanDependencies(std::string const& file, + std::string const& executablePath); + + bool GetFileDependencies(std::vector<std::string> const& names, + std::string const& executablePath, + std::string const& loaderPath, + std::vector<std::string> const& rpaths); + + bool ResolveDependency(std::string const& name, + std::string const& executablePath, + std::string const& loaderPath, + std::vector<std::string> const& rpaths, + std::string& path, bool& resolved); + + bool ResolveExecutablePathDependency(std::string const& name, + std::string const& executablePath, + std::string& path, bool& resolved); + + bool ResolveLoaderPathDependency(std::string const& name, + std::string const& loaderPath, + std::string& path, bool& resolved); + + bool ResolveRPathDependency(std::string const& name, + std::string const& executablePath, + std::string const& loaderPath, + std::vector<std::string> const& rpaths, + std::string& path, bool& resolved); +}; + +#endif // cmBinUtilsMacOSMachOLinker_h diff --git a/Source/cmBinUtilsMacOSMachOOToolGetRuntimeDependenciesTool.cxx b/Source/cmBinUtilsMacOSMachOOToolGetRuntimeDependenciesTool.cxx new file mode 100644 index 0000000..bab2382 --- /dev/null +++ b/Source/cmBinUtilsMacOSMachOOToolGetRuntimeDependenciesTool.cxx @@ -0,0 +1,100 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ + +#include "cmBinUtilsMacOSMachOOToolGetRuntimeDependenciesTool.h" + +#include "cmRuntimeDependencyArchive.h" +#include "cmUVProcessChain.h" + +#include <cmsys/RegularExpression.hxx> + +#include <sstream> + +cmBinUtilsMacOSMachOOToolGetRuntimeDependenciesTool:: + cmBinUtilsMacOSMachOOToolGetRuntimeDependenciesTool( + cmRuntimeDependencyArchive* archive) + : cmBinUtilsMacOSMachOGetRuntimeDependenciesTool(archive) +{ +} + +bool cmBinUtilsMacOSMachOOToolGetRuntimeDependenciesTool::GetFileInfo( + std::string const& file, std::vector<std::string>& libs, + std::vector<std::string>& rpaths) +{ + std::vector<std::string> command; + if (!this->Archive->GetGetRuntimeDependenciesCommand("otool", command)) { + this->SetError("Could not find otool"); + return false; + } + command.emplace_back("-l"); + command.emplace_back(file); + + cmUVProcessChainBuilder builder; + builder.SetBuiltinStream(cmUVProcessChainBuilder::Stream_OUTPUT) + .AddCommand(command); + + auto process = builder.Start(); + if (!process.Valid()) { + std::ostringstream e; + e << "Failed to start otool process for:\n " << file; + this->SetError(e.str()); + return false; + } + + std::string line; + static const cmsys::RegularExpression rpathRegex("^ *cmd LC_RPATH$"); + static const cmsys::RegularExpression loadDylibRegex( + "^ *cmd LC_LOAD_DYLIB$"); + static const cmsys::RegularExpression pathRegex( + "^ *path (.*) \\(offset [0-9]+\\)$"); + static const cmsys::RegularExpression nameRegex( + "^ *name (.*) \\(offset [0-9]+\\)$"); + while (std::getline(*process.OutputStream(), line)) { + cmsys::RegularExpressionMatch cmdMatch; + if (rpathRegex.find(line.c_str(), cmdMatch)) { + if (!std::getline(*process.OutputStream(), line) || + !std::getline(*process.OutputStream(), line)) { + this->SetError("Invalid output from otool"); + return false; + } + + cmsys::RegularExpressionMatch pathMatch; + if (pathRegex.find(line.c_str(), pathMatch)) { + rpaths.push_back(pathMatch.match(1)); + } else { + this->SetError("Invalid output from otool"); + return false; + } + } else if (loadDylibRegex.find(line.c_str(), cmdMatch)) { + if (!std::getline(*process.OutputStream(), line) || + !std::getline(*process.OutputStream(), line)) { + this->SetError("Invalid output from otool"); + return false; + } + + cmsys::RegularExpressionMatch nameMatch; + if (nameRegex.find(line.c_str(), nameMatch)) { + libs.push_back(nameMatch.match(1)); + } else { + this->SetError("Invalid output from otool"); + return false; + } + } + } + + if (!process.Wait()) { + std::ostringstream e; + e << "Failed to wait on otool process for:\n " << file; + this->SetError(e.str()); + return false; + } + auto status = process.GetStatus(); + if (!status[0] || status[0]->ExitStatus != 0) { + std::ostringstream e; + e << "Failed to run otool on:\n " << file; + this->SetError(e.str()); + return false; + } + + return true; +} diff --git a/Source/cmBinUtilsMacOSMachOOToolGetRuntimeDependenciesTool.h b/Source/cmBinUtilsMacOSMachOOToolGetRuntimeDependenciesTool.h new file mode 100644 index 0000000..12bcbc1 --- /dev/null +++ b/Source/cmBinUtilsMacOSMachOOToolGetRuntimeDependenciesTool.h @@ -0,0 +1,25 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ + +#ifndef cmBinUtilsMacOSMachOOToolGetRuntimeDependenciesTool_h +#define cmBinUtilsMacOSMachOOToolGetRuntimeDependenciesTool_h + +#include "cmBinUtilsMacOSMachOGetRuntimeDependenciesTool.h" + +#include <string> +#include <vector> + +class cmRuntimeDependencyArchive; + +class cmBinUtilsMacOSMachOOToolGetRuntimeDependenciesTool + : public cmBinUtilsMacOSMachOGetRuntimeDependenciesTool +{ +public: + cmBinUtilsMacOSMachOOToolGetRuntimeDependenciesTool( + cmRuntimeDependencyArchive* archive); + + bool GetFileInfo(std::string const& file, std::vector<std::string>& libs, + std::vector<std::string>& rpaths) override; +}; + +#endif // cmBinUtilsMacOSMachOOToolGetRuntimeDependenciesTool_h diff --git a/Source/cmBinUtilsWindowsPEDumpbinGetRuntimeDependenciesTool.cxx b/Source/cmBinUtilsWindowsPEDumpbinGetRuntimeDependenciesTool.cxx new file mode 100644 index 0000000..2b35e30 --- /dev/null +++ b/Source/cmBinUtilsWindowsPEDumpbinGetRuntimeDependenciesTool.cxx @@ -0,0 +1,67 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ + +#include "cmBinUtilsWindowsPEDumpbinGetRuntimeDependenciesTool.h" +#include "cmRuntimeDependencyArchive.h" +#include "cmUVProcessChain.h" + +#include <cmsys/RegularExpression.hxx> + +#include <sstream> + +cmBinUtilsWindowsPEDumpbinGetRuntimeDependenciesTool:: + cmBinUtilsWindowsPEDumpbinGetRuntimeDependenciesTool( + cmRuntimeDependencyArchive* archive) + : cmBinUtilsWindowsPEGetRuntimeDependenciesTool(archive) +{ +} + +bool cmBinUtilsWindowsPEDumpbinGetRuntimeDependenciesTool::GetFileInfo( + const std::string& file, std::vector<std::string>& needed) +{ + cmUVProcessChainBuilder builder; + builder.SetBuiltinStream(cmUVProcessChainBuilder::Stream_OUTPUT); + + std::vector<std::string> command; + if (!this->Archive->GetGetRuntimeDependenciesCommand("dumpbin", command)) { + this->SetError("Could not find dumpbin"); + return false; + } + command.emplace_back("/dependents"); + command.push_back(file); + builder.AddCommand(command); + + auto process = builder.Start(); + if (!process.Valid()) { + std::ostringstream e; + e << "Failed to start dumpbin process for:\n " << file; + this->SetError(e.str()); + return false; + } + + std::string line; + static const cmsys::RegularExpression regex( + "^ ([^\n]*\\.[Dd][Ll][Ll])\r$"); + while (std::getline(*process.OutputStream(), line)) { + cmsys::RegularExpressionMatch match; + if (regex.find(line.c_str(), match)) { + needed.push_back(match.match(1)); + } + } + + if (!process.Wait()) { + std::ostringstream e; + e << "Failed to wait on dumpbin process for:\n " << file; + this->SetError(e.str()); + return false; + } + auto status = process.GetStatus(); + if (!status[0] || status[0]->ExitStatus != 0) { + std::ostringstream e; + e << "Failed to run dumpbin on:\n " << file; + this->SetError(e.str()); + return false; + } + + return true; +} diff --git a/Source/cmBinUtilsWindowsPEDumpbinGetRuntimeDependenciesTool.h b/Source/cmBinUtilsWindowsPEDumpbinGetRuntimeDependenciesTool.h new file mode 100644 index 0000000..4c17f8d --- /dev/null +++ b/Source/cmBinUtilsWindowsPEDumpbinGetRuntimeDependenciesTool.h @@ -0,0 +1,25 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ + +#ifndef cmBinUtilsWindowsPEDumpbinGetRuntimeDependenciesTool_h +#define cmBinUtilsWindowsPEDumpbinGetRuntimeDependenciesTool_h + +#include "cmBinUtilsWindowsPEGetRuntimeDependenciesTool.h" + +#include <string> +#include <vector> + +class cmRuntimeDependencyArchive; + +class cmBinUtilsWindowsPEDumpbinGetRuntimeDependenciesTool + : public cmBinUtilsWindowsPEGetRuntimeDependenciesTool +{ +public: + cmBinUtilsWindowsPEDumpbinGetRuntimeDependenciesTool( + cmRuntimeDependencyArchive* archive); + + bool GetFileInfo(const std::string& file, + std::vector<std::string>& needed) override; +}; + +#endif // cmBinUtilsWindowsPEDumpbinGetRuntimeDependenciesTool_h diff --git a/Source/cmBinUtilsWindowsPEGetRuntimeDependenciesTool.cxx b/Source/cmBinUtilsWindowsPEGetRuntimeDependenciesTool.cxx new file mode 100644 index 0000000..f5a4431 --- /dev/null +++ b/Source/cmBinUtilsWindowsPEGetRuntimeDependenciesTool.cxx @@ -0,0 +1,18 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ + +#include "cmBinUtilsWindowsPEGetRuntimeDependenciesTool.h" +#include "cmRuntimeDependencyArchive.h" + +cmBinUtilsWindowsPEGetRuntimeDependenciesTool:: + cmBinUtilsWindowsPEGetRuntimeDependenciesTool( + cmRuntimeDependencyArchive* archive) + : Archive(archive) +{ +} + +void cmBinUtilsWindowsPEGetRuntimeDependenciesTool::SetError( + const std::string& error) +{ + this->Archive->SetError(error); +} diff --git a/Source/cmBinUtilsWindowsPEGetRuntimeDependenciesTool.h b/Source/cmBinUtilsWindowsPEGetRuntimeDependenciesTool.h new file mode 100644 index 0000000..e9e402b --- /dev/null +++ b/Source/cmBinUtilsWindowsPEGetRuntimeDependenciesTool.h @@ -0,0 +1,28 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ + +#ifndef cmBinUtilsWindowsPEGetRuntimeDependenciesTool_h +#define cmBinUtilsWindowsPEGetRuntimeDependenciesTool_h + +#include <string> +#include <vector> + +class cmRuntimeDependencyArchive; + +class cmBinUtilsWindowsPEGetRuntimeDependenciesTool +{ +public: + cmBinUtilsWindowsPEGetRuntimeDependenciesTool( + cmRuntimeDependencyArchive* archive); + virtual ~cmBinUtilsWindowsPEGetRuntimeDependenciesTool() = default; + + virtual bool GetFileInfo(const std::string& file, + std::vector<std::string>& needed) = 0; + +protected: + cmRuntimeDependencyArchive* Archive; + + void SetError(const std::string& error); +}; + +#endif // cmBinUtilsWindowsPEGetRuntimeDependenciesTool_h diff --git a/Source/cmBinUtilsWindowsPELinker.cxx b/Source/cmBinUtilsWindowsPELinker.cxx new file mode 100644 index 0000000..5a9ad66 --- /dev/null +++ b/Source/cmBinUtilsWindowsPELinker.cxx @@ -0,0 +1,123 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ + +#include "cmBinUtilsWindowsPELinker.h" + +#include "cmBinUtilsWindowsPEDumpbinGetRuntimeDependenciesTool.h" +#include "cmBinUtilsWindowsPEObjdumpGetRuntimeDependenciesTool.h" +#include "cmRuntimeDependencyArchive.h" +#include "cmStringAlgorithms.h" +#include "cmSystemTools.h" + +#include <sstream> +#include <vector> + +#include "cm_memory.hxx" + +#ifdef _WIN32 +# include <windows.h> +#endif + +cmBinUtilsWindowsPELinker::cmBinUtilsWindowsPELinker( + cmRuntimeDependencyArchive* archive) + : cmBinUtilsLinker(archive) +{ +} + +bool cmBinUtilsWindowsPELinker::Prepare() +{ + std::string tool = this->Archive->GetGetRuntimeDependenciesTool(); + if (tool.empty()) { + std::vector<std::string> command; + if (this->Archive->GetGetRuntimeDependenciesCommand("dumpbin", command)) { + tool = "dumpbin"; + } else { + tool = "objdump"; + } + } + if (tool == "dumpbin") { + this->Tool = + cm::make_unique<cmBinUtilsWindowsPEDumpbinGetRuntimeDependenciesTool>( + this->Archive); + } else if (tool == "objdump") { + this->Tool = + cm::make_unique<cmBinUtilsWindowsPEObjdumpGetRuntimeDependenciesTool>( + this->Archive); + } else { + std::ostringstream e; + e << "Invalid value for CMAKE_GET_RUNTIME_DEPENDENCIES_TOOL: " << tool; + this->SetError(e.str()); + return false; + } + + return true; +} + +bool cmBinUtilsWindowsPELinker::ScanDependencies( + std::string const& file, cmStateEnums::TargetType /* unused */) +{ + std::vector<std::string> needed; + if (!this->Tool->GetFileInfo(file, needed)) { + return false; + } + for (auto& n : needed) { + n = cmSystemTools::LowerCase(n); + } + std::string origin = cmSystemTools::GetFilenamePath(file); + + for (auto const& lib : needed) { + if (!this->Archive->IsPreExcluded(lib)) { + std::string path; + bool resolved = false; + if (!this->ResolveDependency(lib, origin, path, resolved)) { + return false; + } + if (resolved) { + if (!this->Archive->IsPostExcluded(path)) { + bool unique; + this->Archive->AddResolvedPath(lib, path, unique); + if (unique && + !this->ScanDependencies(path, cmStateEnums::SHARED_LIBRARY)) { + return false; + } + } + } else { + this->Archive->AddUnresolvedPath(lib); + } + } + } + + return true; +} + +bool cmBinUtilsWindowsPELinker::ResolveDependency(std::string const& name, + std::string const& origin, + std::string& path, + bool& resolved) +{ + auto dirs = this->Archive->GetSearchDirectories(); + +#ifdef _WIN32 + char buf[MAX_PATH]; + unsigned int len; + if ((len = GetWindowsDirectoryA(buf, MAX_PATH)) > 0) { + dirs.insert(dirs.begin(), std::string(buf, len)); + } + if ((len = GetSystemDirectoryA(buf, MAX_PATH)) > 0) { + dirs.insert(dirs.begin(), std::string(buf, len)); + } +#endif + + dirs.insert(dirs.begin(), origin); + + for (auto const& searchPath : dirs) { + path = cmStrCat(searchPath, '/', name); + if (cmSystemTools::PathExists(path)) { + resolved = true; + return true; + } + } + + resolved = false; + return true; +} diff --git a/Source/cmBinUtilsWindowsPELinker.h b/Source/cmBinUtilsWindowsPELinker.h new file mode 100644 index 0000000..8d2bf4b --- /dev/null +++ b/Source/cmBinUtilsWindowsPELinker.h @@ -0,0 +1,33 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ + +#ifndef cmBinUtilsWindowsPELinker_h +#define cmBinUtilsWindowsPELinker_h + +#include "cmBinUtilsLinker.h" +#include "cmBinUtilsWindowsPEGetRuntimeDependenciesTool.h" +#include "cmStateTypes.h" + +#include <memory> +#include <string> + +class cmRuntimeDependencyArchive; + +class cmBinUtilsWindowsPELinker : public cmBinUtilsLinker +{ +public: + cmBinUtilsWindowsPELinker(cmRuntimeDependencyArchive* archive); + + bool Prepare() override; + + bool ScanDependencies(std::string const& file, + cmStateEnums::TargetType type) override; + +private: + std::unique_ptr<cmBinUtilsWindowsPEGetRuntimeDependenciesTool> Tool; + + bool ResolveDependency(std::string const& name, std::string const& origin, + std::string& path, bool& resolved); +}; + +#endif // cmBinUtilsWindowsPELinker_h diff --git a/Source/cmBinUtilsWindowsPEObjdumpGetRuntimeDependenciesTool.cxx b/Source/cmBinUtilsWindowsPEObjdumpGetRuntimeDependenciesTool.cxx new file mode 100644 index 0000000..1f27003 --- /dev/null +++ b/Source/cmBinUtilsWindowsPEObjdumpGetRuntimeDependenciesTool.cxx @@ -0,0 +1,67 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ + +#include "cmBinUtilsWindowsPEObjdumpGetRuntimeDependenciesTool.h" +#include "cmRuntimeDependencyArchive.h" +#include "cmUVProcessChain.h" + +#include <cmsys/RegularExpression.hxx> + +#include <sstream> + +cmBinUtilsWindowsPEObjdumpGetRuntimeDependenciesTool:: + cmBinUtilsWindowsPEObjdumpGetRuntimeDependenciesTool( + cmRuntimeDependencyArchive* archive) + : cmBinUtilsWindowsPEGetRuntimeDependenciesTool(archive) +{ +} + +bool cmBinUtilsWindowsPEObjdumpGetRuntimeDependenciesTool::GetFileInfo( + const std::string& file, std::vector<std::string>& needed) +{ + cmUVProcessChainBuilder builder; + builder.SetBuiltinStream(cmUVProcessChainBuilder::Stream_OUTPUT); + + std::vector<std::string> command; + if (!this->Archive->GetGetRuntimeDependenciesCommand("objdump", command)) { + this->SetError("Could not find objdump"); + return false; + } + command.emplace_back("-p"); + command.push_back(file); + builder.AddCommand(command); + + auto process = builder.Start(); + if (!process.Valid()) { + std::ostringstream e; + e << "Failed to start objdump process for:\n " << file; + this->SetError(e.str()); + return false; + } + + std::string line; + static const cmsys::RegularExpression regex( + "^\t*DLL Name: ([^\n]*\\.[Dd][Ll][Ll])\r$"); + while (std::getline(*process.OutputStream(), line)) { + cmsys::RegularExpressionMatch match; + if (regex.find(line.c_str(), match)) { + needed.push_back(match.match(1)); + } + } + + if (!process.Wait()) { + std::ostringstream e; + e << "Failed to wait on objdump process for:\n " << file; + this->SetError(e.str()); + return false; + } + auto status = process.GetStatus(); + if (!status[0] || status[0]->ExitStatus != 0) { + std::ostringstream e; + e << "Failed to run objdump on:\n " << file; + this->SetError(e.str()); + return false; + } + + return true; +} diff --git a/Source/cmBinUtilsWindowsPEObjdumpGetRuntimeDependenciesTool.h b/Source/cmBinUtilsWindowsPEObjdumpGetRuntimeDependenciesTool.h new file mode 100644 index 0000000..1d1a5b0 --- /dev/null +++ b/Source/cmBinUtilsWindowsPEObjdumpGetRuntimeDependenciesTool.h @@ -0,0 +1,25 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ + +#ifndef cmBinUtilsWindowsPEObjdumpGetRuntimeDependenciesTool_h +#define cmBinUtilsWindowsPEObjdumpGetRuntimeDependenciesTool_h + +#include "cmBinUtilsWindowsPEGetRuntimeDependenciesTool.h" + +#include <string> +#include <vector> + +class cmRuntimeDependencyArchive; + +class cmBinUtilsWindowsPEObjdumpGetRuntimeDependenciesTool + : public cmBinUtilsWindowsPEGetRuntimeDependenciesTool +{ +public: + cmBinUtilsWindowsPEObjdumpGetRuntimeDependenciesTool( + cmRuntimeDependencyArchive* archive); + + bool GetFileInfo(const std::string& file, + std::vector<std::string>& needed) override; +}; + +#endif // cmBinUtilsWindowsPEObjdumpGetRuntimeDependenciesTool_h 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 3b18567..e6ce6fe 100644 --- a/Source/cmBreakCommand.h +++ b/Source/cmBreakCommand.h @@ -8,29 +8,14 @@ #include <string> #include <vector> -#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. - */ - cmCommand* Clone() override { return new 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/cmBuildCommand.cxx b/Source/cmBuildCommand.cxx index 428a0b2..e9e1d49 100644 --- a/Source/cmBuildCommand.cxx +++ b/Source/cmBuildCommand.cxx @@ -92,7 +92,7 @@ bool cmBuildCommand::MainSignature(std::vector<std::string> const& args) this->Makefile->GetGlobalGenerator()->GenerateCMakeBuildCommand( target, configuration, "", this->Makefile->IgnoreErrorsCMP0061()); - this->Makefile->AddDefinition(variable, makecommand.c_str()); + this->Makefile->AddDefinition(variable, makecommand); return true; } diff --git a/Source/cmBuildCommand.h b/Source/cmBuildCommand.h index e0529a4..d373103 100644 --- a/Source/cmBuildCommand.h +++ b/Source/cmBuildCommand.h @@ -8,6 +8,8 @@ #include <string> #include <vector> +#include "cm_memory.hxx" + #include "cmCommand.h" class cmExecutionStatus; @@ -23,7 +25,10 @@ public: /** * This is a virtual constructor for the command. */ - cmCommand* Clone() override { return new cmBuildCommand; } + std::unique_ptr<cmCommand> Clone() override + { + return cm::make_unique<cmBuildCommand>(); + } /** * This is called when the command is first encountered in 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 4bb72d1..37a7268 100644 --- a/Source/cmBuildNameCommand.h +++ b/Source/cmBuildNameCommand.h @@ -8,16 +8,9 @@ #include <string> #include <vector> -#include "cmCommand.h" - class cmExecutionStatus; -class cmBuildNameCommand : public cmCommand -{ -public: - cmCommand* Clone() override { return new 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 54f08bb..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.c_str()); + 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 b871641..79e3f27 100644 --- a/Source/cmCMakeHostSystemInformationCommand.h +++ b/Source/cmCMakeHostSystemInformationCommand.h @@ -5,48 +5,18 @@ #include "cmConfigure.h" // IWYU pragma: keep -#include <stddef.h> #include <string> #include <vector> -#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. - */ - cmCommand* Clone() override - { - return new 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 4b4bca2..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,13 +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.c_str()); + status.GetMakefile().AddDefinition("CMAKE_MINIMUM_REQUIRED_VERSION", + version_min); // Get the current version number. unsigned int current_major = cmVersion::GetMajorVersion(); @@ -80,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; } @@ -96,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; } @@ -150,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 f9b61e1..53f78f6 100644 --- a/Source/cmCMakeMinimumRequired.h +++ b/Source/cmCMakeMinimumRequired.h @@ -8,33 +8,14 @@ #include <string> #include <vector> -#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. - */ - cmCommand* Clone() override { return new 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 8da5ef7..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,13 +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).c_str()); + status.GetMakefile().AddDefinition(var, cmPolicies::GetPolicyWarning(pid)); return true; } +} diff --git a/Source/cmCMakePolicyCommand.h b/Source/cmCMakePolicyCommand.h index cca1406..ba9397d 100644 --- a/Source/cmCMakePolicyCommand.h +++ b/Source/cmCMakePolicyCommand.h @@ -8,36 +8,15 @@ #include <string> #include <vector> -#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. - */ - cmCommand* Clone() override { return new 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 255a8e6..f0c1845 100644 --- a/Source/cmCPluginAPI.cxx +++ b/Source/cmCPluginAPI.cxx @@ -65,8 +65,10 @@ unsigned int CCONV cmGetMinorVersion(void*) void CCONV cmAddDefinition(void* arg, const char* name, const char* value) { - cmMakefile* mf = static_cast<cmMakefile*>(arg); - mf->AddDefinition(name, value); + if (value) { + cmMakefile* mf = static_cast<cmMakefile*>(arg); + mf->AddDefinition(name, value); + } } /* Add a definition to this makefile and the global cmake cache. */ @@ -421,7 +423,7 @@ int CCONV cmExecuteCommand(void* arg, const char* name, int numArgs, // Assume all arguments are quoted. lff.Arguments.emplace_back(args[i], cmListFileArgument::Quoted, 0); } - cmExecutionStatus status; + cmExecutionStatus status(*mf); return mf->ExecuteCommand(lff, status); } @@ -606,7 +608,7 @@ int CCONV cmSourceFileGetPropertyAsBool(void* arg, const char* prop) if (cmSourceFile* rsf = sf->RealSourceFile) { return rsf->GetPropertyAsBool(prop) ? 1 : 0; } - return cmSystemTools::IsOn(cmSourceFileGetProperty(arg, prop)) ? 1 : 0; + return cmIsOn(cmSourceFileGetProperty(arg, prop)) ? 1 : 0; } void CCONV cmSourceFileSetProperty(void* arg, const char* prop, @@ -688,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; @@ -700,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 d1226c3..f51ed0b 100644 --- a/Source/cmCTest.cxx +++ b/Source/cmCTest.cxx @@ -15,7 +15,6 @@ #include <ctype.h> #include <iostream> #include <map> -#include <memory> // IWYU pragma: keep #include <sstream> #include <stdio.h> #include <stdlib.h> @@ -30,6 +29,8 @@ # include <unistd.h> // IWYU pragma: keep #endif +#include "cm_memory.hxx" + #include "cmAlgorithms.h" #include "cmCTestBuildAndTestHandler.h" #include "cmCTestBuildHandler.h" @@ -51,6 +52,7 @@ #include "cmState.h" #include "cmStateSnapshot.h" #include "cmStateTypes.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmVersion.h" #include "cmVersionConfig.h" @@ -153,7 +155,7 @@ struct cmCTest::Private bool TomorrowTag = false; int TestModel = cmCTest::EXPERIMENTAL; - std::string SpecificTrack; + std::string SpecificGroup; cmDuration TimeOut = cmDuration::zero(); @@ -321,12 +323,11 @@ cmCTest::cmCTest() { std::string envValue; if (cmSystemTools::GetEnv("CTEST_OUTPUT_ON_FAILURE", envValue)) { - this->Impl->OutputTestOutputOnTestFailure = - !cmSystemTools::IsOff(envValue); + this->Impl->OutputTestOutputOnTestFailure = !cmIsOff(envValue); } envValue.clear(); if (cmSystemTools::GetEnv("CTEST_PROGRESS_OUTPUT", envValue)) { - this->Impl->TestProgressOutput = !cmSystemTools::IsOff(envValue); + this->Impl->TestProgressOutput = !cmIsOff(envValue); } this->Impl->Parts[PartStart].SetName("Start"); @@ -507,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) && @@ -563,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()); } @@ -604,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, @@ -640,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)) { @@ -661,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; } @@ -752,7 +750,7 @@ bool cmCTest::UpdateCTestConfiguration() std::string const& testLoad = this->GetCTestConfiguration("TestLoad"); if (!testLoad.empty()) { unsigned long load; - if (cmSystemTools::StringToULong(testLoad.c_str(), &load)) { + if (cmStrToULong(testLoad, &load)) { this->SetTestLoad(load); } else { cmCTestLog(this, WARNING, @@ -761,7 +759,7 @@ bool cmCTest::UpdateCTestConfiguration() } if (this->Impl->ProduceXML) { this->Impl->CompressXMLFiles = - cmSystemTools::IsOn(this->GetCTestConfiguration("CompressSubmission")); + cmIsOn(this->GetCTestConfiguration("CompressSubmission")); } return true; } @@ -855,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 { @@ -1020,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: @@ -1098,9 +1095,10 @@ int cmCTest::RunMakeCommand(const std::string& command, std::string& output, cmProcessOutput processOutput(encoding); std::string strdata; cmCTestLog(this, HANDLER_PROGRESS_OUTPUT, - " Each . represents " << tick_len << " bytes of output" - << std::endl - << " " << std::flush); + " Each . represents " << tick_len + << " bytes of output\n" + " " + << std::flush); while (cmsysProcess_WaitForData(cp, &data, &length, nullptr)) { processOutput.DecodeText(data, length, strdata); for (char& cc : strdata) { @@ -1115,8 +1113,7 @@ int cmCTest::RunMakeCommand(const std::string& command, std::string& output, if (tick % tick_line_len == 0 && tick > 0) { cmCTestLog(this, HANDLER_PROGRESS_OUTPUT, " Size: " << int((double(output.size()) / 1024.0) + 1) - << "K" << std::endl - << " " << std::flush); + << "K\n " << std::flush); } } cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, @@ -1221,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); } @@ -1319,23 +1314,19 @@ 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 - << std::flush); + 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; } - cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, - outerr << std::endl - << std::flush); + cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, outerr << std::endl); } cmsysProcess_Delete(cp); @@ -1455,8 +1446,7 @@ void cmCTest::AddSiteProperties(cmXMLWriter& xml) if (labels) { xml.StartElement("Labels"); std::string l = labels; - std::vector<std::string> args; - cmSystemTools::ExpandListArgument(l, args); + std::vector<std::string> args = cmExpandedList(l); for (std::string const& i : args) { xml.Element("Label", i); } @@ -1488,8 +1478,7 @@ std::vector<std::string> cmCTest::GetLabelsForSubprojects() { std::string labelsForSubprojects = this->GetCTestConfiguration("LabelsForSubprojects"); - std::vector<std::string> subprojects; - cmSystemTools::ExpandListArgument(labelsForSubprojects, subprojects); + std::vector<std::string> subprojects = cmExpandedList(labelsForSubprojects); // sort the array std::sort(subprojects.begin(), subprojects.end()); @@ -1856,7 +1845,7 @@ bool cmCTest::HandleCommandLineArguments(size_t& i, } i++; long repeat = 1; - if (!cmSystemTools::StringToLong(args[i].c_str(), &repeat)) { + if (!cmStrToLong(args[i], &repeat)) { errormsg = "'--repeat-until-fail' given non-integer value '" + args[i] + "'"; return false; @@ -1870,7 +1859,7 @@ bool cmCTest::HandleCommandLineArguments(size_t& i, if (this->CheckArgument(arg, "--test-load") && i < args.size() - 1) { i++; unsigned long load; - if (cmSystemTools::StringToULong(args[i].c_str(), &load)) { + if (cmStrToULong(args[i], &load)) { this->SetTestLoad(load); } else { cmCTestLog(this, WARNING, @@ -1911,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; @@ -1944,7 +1939,7 @@ bool cmCTest::HandleCommandLineArguments(size_t& i, i < args.size() - 1) { i++; long outputSize; - if (cmSystemTools::StringToLong(args[i].c_str(), &outputSize)) { + if (cmStrToLong(args[i], &outputSize)) { this->Impl->TestHandler.SetTestOutputSizePassed(int(outputSize)); } else { cmCTestLog(this, WARNING, @@ -1956,7 +1951,7 @@ bool cmCTest::HandleCommandLineArguments(size_t& i, i < args.size() - 1) { i++; long outputSize; - if (cmSystemTools::StringToLong(args[i].c_str(), &outputSize)) { + if (cmStrToLong(args[i], &outputSize)) { this->Impl->TestHandler.SetTestOutputSizeFailed(int(outputSize)); } else { cmCTestLog(this, WARNING, @@ -1967,7 +1962,7 @@ bool cmCTest::HandleCommandLineArguments(size_t& i, if (this->CheckArgument(arg, "-N", "--show-only")) { this->Impl->ShowOnly = true; } - if (cmSystemTools::StringStartsWith(arg.c_str(), "--show-only=")) { + if (cmHasLiteralPrefix(arg, "--show-only=")) { this->Impl->ShowOnly = true; // Check if a specific format is requested. Defaults to human readable @@ -2003,7 +1998,7 @@ bool cmCTest::HandleCommandLineArguments(size_t& i, if (this->CheckArgument(arg, "--interactive-debug-mode") && i < args.size() - 1) { i++; - this->Impl->InteractiveDebugMode = cmSystemTools::IsOn(args[i]); + this->Impl->InteractiveDebugMode = cmIsOn(args[i]); } if (this->CheckArgument(arg, "--submit-index") && i < args.size() - 1) { i++; @@ -2132,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 } @@ -2229,7 +2229,7 @@ int cmCTest::Run(std::vector<std::string>& args, std::string* output) // attempts are simply ignored since previous ctest versions ignore // this too. (As well as many other unknown command line args.) // - if (arg != "-D" && cmSystemTools::StringStartsWith(arg.c_str(), "-D")) { + if (arg != "-D" && cmHasLiteralPrefix(arg, "-D")) { std::string input = arg.substr(2); this->AddVariableDefinition(input); } @@ -2425,7 +2425,7 @@ int cmCTest::RunCMakeAndTest(std::string* output) cmCTestBuildAndTestHandler* handler = this->GetBuildAndTestHandler(); int retv = handler->ProcessHandler(); *output = handler->GetOutput(); -#ifdef CMAKE_BUILD_WITH_CMAKE +#ifndef CMAKE_BOOTSTRAP cmDynamicLoader::FlushCache(); #endif if (retv != 0) { @@ -2502,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, @@ -2523,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; @@ -2567,7 +2565,7 @@ void cmCTest::PopulateCustomVector(cmMakefile* mf, const std::string& def, cmCTestLog(this, DEBUG, "PopulateCustomVector: " << def << std::endl); vec.clear(); - cmSystemTools::ExpandListArgument(dval, vec); + cmExpandList(dval, vec); for (std::string const& it : vec) { cmCTestLog(this, DEBUG, " -- " << it << std::endl); @@ -2676,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()) { @@ -2772,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) @@ -3077,11 +3074,11 @@ void cmCTest::Log(int logType, const char* file, int line, const char* msg, } else { *this->Impl->OutputLogFile << cmCTestStringLogType[logType]; } - *this->Impl->OutputLogFile << "] " << std::endl << std::flush; + *this->Impl->OutputLogFile << "] " << std::endl; } *this->Impl->OutputLogFile << msg << std::flush; if (logType != this->Impl->OutputLogFileLastTag) { - *this->Impl->OutputLogFile << std::endl << std::flush; + *this->Impl->OutputLogFile << std::endl; this->Impl->OutputLogFileLastTag = logType; } } @@ -3194,7 +3191,7 @@ void cmCTest::OutputTestErrors(std::vector<char> const& process_output) if (!process_output.empty()) { test_outputs.append(process_output.data(), process_output.size()); } - cmCTestLog(this, HANDLER_OUTPUT, test_outputs << std::endl << std::flush); + cmCTestLog(this, HANDLER_OUTPUT, test_outputs << std::endl); } bool cmCTest::CompressString(std::string& str) diff --git a/Source/cmCTest.h b/Source/cmCTest.h index d300c33..7fe3455 100644 --- a/Source/cmCTest.h +++ b/Source/cmCTest.h @@ -10,7 +10,7 @@ #include <chrono> #include <map> -#include <memory> // IWYU pragma: keep +#include <memory> #include <sstream> #include <string> #include <time.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 358f095..cf28cdb 100644 --- a/Source/cmCacheManager.cxx +++ b/Source/cmCacheManager.cxx @@ -14,6 +14,7 @@ #include "cmMessageType.h" #include "cmMessenger.h" #include "cmState.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmVersion.h" @@ -25,9 +26,7 @@ cmCacheManager::cmCacheManager() void cmCacheManager::CleanCMakeFiles(const std::string& path) { - std::string glob = path; - glob += "/CMakeFiles"; - glob += "/*.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; - cmSystemTools::ExpandListArgument(e.Value, paths); + std::vector<std::string> paths = cmExpandedList(e.Value); const char* sep = ""; e.Value = ""; for (std::string& i : paths) { @@ -615,12 +604,12 @@ void cmCacheManager::CacheIterator::SetValue(const char* value) bool cmCacheManager::CacheIterator::GetValueAsBool() const { - return cmSystemTools::IsOn(this->GetEntry().Value); + return cmIsOn(this->GetEntry().Value); } std::vector<std::string> cmCacheManager::CacheEntry::GetPropertyList() const { - return this->Properties.GetPropertyList(); + return this->Properties.GetKeys(); } const char* cmCacheManager::CacheEntry::GetProperty( @@ -695,7 +684,7 @@ bool cmCacheManager::CacheIterator::GetPropertyAsBool( const std::string& prop) const { if (const char* value = this->GetProperty(prop)) { - return cmSystemTools::IsOn(value); + return cmIsOn(value); } return false; } diff --git a/Source/cmCallVisualStudioMacro.cxx b/Source/cmCallVisualStudioMacro.cxx index f7a2244..9e152ff 100644 --- a/Source/cmCallVisualStudioMacro.cxx +++ b/Source/cmCallVisualStudioMacro.cxx @@ -4,6 +4,7 @@ #include <sstream> +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #if defined(_MSC_VER) @@ -328,8 +329,7 @@ HRESULT FindVisualStudioInstances(const std::string& slnFile, if (SUCCEEDED(hr)) { std::map<std::string, IUnknownPtr>::iterator it; for (it = mrot.begin(); it != mrot.end(); ++it) { - if (cmSystemTools::StringStartsWith(it->first.c_str(), - "!VisualStudio.DTE.")) { + if (cmHasLiteralPrefix(it->first, "!VisualStudio.DTE.")) { IDispatchPtr disp(it->second); if (disp != (IDispatch*)0) { std::string slnName; diff --git a/Source/cmCommand.cxx b/Source/cmCommand.cxx index d349c91..0c2734e 100644 --- a/Source/cmCommand.cxx +++ b/Source/cmCommand.cxx @@ -2,11 +2,19 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmCommand.h" +#include <utility> + +#include "cmExecutionStatus.h" #include "cmMakefile.h" -class cmExecutionStatus; struct cmListFileArgument; +void cmCommand::SetExecutionStatus(cmExecutionStatus* status) +{ + this->Status = status; + this->Makefile = &status->GetMakefile(); +} + bool cmCommand::InvokeInitialPass(const std::vector<cmListFileArgument>& args, cmExecutionStatus& status) { @@ -19,15 +27,33 @@ bool cmCommand::InvokeInitialPass(const std::vector<cmListFileArgument>& args, return this->InitialPass(expandedArguments, status); } -const char* cmCommand::GetError() +void cmCommand::SetError(const std::string& e) { - if (this->Error.empty()) { - return "unknown error."; - } - return this->Error.c_str(); + this->Status->SetError(e); } -void cmCommand::SetError(const std::string& e) +cmLegacyCommandWrapper::cmLegacyCommandWrapper(std::unique_ptr<cmCommand> cmd) + : Command(std::move(cmd)) +{ +} + +cmLegacyCommandWrapper::cmLegacyCommandWrapper( + cmLegacyCommandWrapper const& other) + : Command(other.Command->Clone()) +{ +} + +cmLegacyCommandWrapper& cmLegacyCommandWrapper::operator=( + cmLegacyCommandWrapper const& other) +{ + this->Command = other.Command->Clone(); + return *this; +} + +bool cmLegacyCommandWrapper::operator()( + std::vector<cmListFileArgument> const& args, cmExecutionStatus& status) const { - this->Error = e; + auto cmd = this->Command->Clone(); + cmd->SetExecutionStatus(&status); + return cmd->InvokeInitialPass(args, status); } diff --git a/Source/cmCommand.h b/Source/cmCommand.h index 9ccd773..bcb178d 100644 --- a/Source/cmCommand.h +++ b/Source/cmCommand.h @@ -5,6 +5,7 @@ #include "cmConfigure.h" // IWYU pragma: keep +#include <memory> #include <string> #include <vector> @@ -41,16 +42,18 @@ public: /** * Specify the makefile. */ - void SetMakefile(cmMakefile* m) { this->Makefile = m; } cmMakefile* GetMakefile() { return this->Makefile; } + void SetExecutionStatus(cmExecutionStatus* s); + cmExecutionStatus* GetExecutionStatus() { return this->Status; }; + /** * This is called by the cmMakefile when the command is first * encountered in the CMakeLists.txt file. It expands the command's * arguments and then invokes the InitialPass. */ - virtual bool InvokeInitialPass(const std::vector<cmListFileArgument>& args, - cmExecutionStatus& status); + bool InvokeInitialPass(const std::vector<cmListFileArgument>& args, + cmExecutionStatus& status); /** * This is called when the command is first encountered in @@ -60,27 +63,9 @@ public: cmExecutionStatus&) = 0; /** - * This is called at the end after all the information - * specified by the command is accumulated. Most commands do - * not implement this method. At this point, reading and - * writing to the cache can be done. - */ - virtual void FinalPass() {} - - /** - * Does this command have a final pass? Query after InitialPass. - */ - virtual bool HasFinalPass() const { return false; } - - /** * This is a virtual constructor for the command. */ - virtual cmCommand* Clone() = 0; - - /** - * Return the last error string. - */ - const char* GetError(); + virtual std::unique_ptr<cmCommand> Clone() = 0; /** * Set the error message @@ -91,7 +76,25 @@ protected: cmMakefile* Makefile = nullptr; private: - std::string Error; + cmExecutionStatus* Status = nullptr; +}; + +class cmLegacyCommandWrapper +{ +public: + explicit cmLegacyCommandWrapper(std::unique_ptr<cmCommand> cmd); + + cmLegacyCommandWrapper(cmLegacyCommandWrapper const& other); + cmLegacyCommandWrapper& operator=(cmLegacyCommandWrapper const& other); + + cmLegacyCommandWrapper(cmLegacyCommandWrapper&&) = default; + cmLegacyCommandWrapper& operator=(cmLegacyCommandWrapper&&) = default; + + bool operator()(std::vector<cmListFileArgument> const& args, + cmExecutionStatus& status) const; + +private: + std::unique_ptr<cmCommand> Command; }; #endif diff --git a/Source/cmCommandArgumentParserHelper.cxx b/Source/cmCommandArgumentParserHelper.cxx index ca29967..b368b3a 100644 --- a/Source/cmCommandArgumentParserHelper.cxx +++ b/Source/cmCommandArgumentParserHelper.cxx @@ -5,6 +5,7 @@ #include "cmCommandArgumentLexer.h" #include "cmMakefile.h" #include "cmState.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include <iostream> @@ -58,7 +59,7 @@ const char* cmCommandArgumentParserHelper::ExpandSpecialVariable( std::string str; if (cmSystemTools::GetEnv(var, str)) { if (this->EscapeQuotes) { - return this->AddString(cmSystemTools::EscapeQuotes(str)); + return this->AddString(cmEscapeQuotes(str)); } return this->AddString(str); } @@ -68,7 +69,7 @@ const char* cmCommandArgumentParserHelper::ExpandSpecialVariable( if (const std::string* c = this->Makefile->GetState()->GetInitializedCacheValue(var)) { if (this->EscapeQuotes) { - return this->AddString(cmSystemTools::EscapeQuotes(*c)); + return this->AddString(cmEscapeQuotes(*c)); } return this->AddString(*c); } @@ -87,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) { @@ -99,7 +98,7 @@ const char* cmCommandArgumentParserHelper::ExpandVariable(const char* var) } } if (this->EscapeQuotes && value) { - return this->AddString(cmSystemTools::EscapeQuotes(value)); + return this->AddString(cmEscapeQuotes(value)); } return this->AddString(value ? value : ""); } @@ -123,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 63c5397..ead16d2 100644 --- a/Source/cmCommands.cxx +++ b/Source/cmCommands.cxx @@ -1,5 +1,8 @@ /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying file Copyright.txt or https://cmake.org/licensing for details. */ + +#include "cm_memory.hxx" + #include "cmCommands.h" #include "cmPolicies.h" #include "cmState.h" @@ -17,6 +20,7 @@ #include "cmBuildCommand.h" #include "cmCMakeMinimumRequired.h" #include "cmCMakePolicyCommand.h" +#include "cmCommand.h" #include "cmConfigureFileCommand.h" #include "cmContinueCommand.h" #include "cmCreateTestSourceList.h" @@ -80,7 +84,7 @@ #include "cmUnsetCommand.h" #include "cmWhileCommand.h" -#if defined(CMAKE_BUILD_WITH_CMAKE) +#if !defined(CMAKE_BOOTSTRAP) # include "cmAddCompileOptionsCommand.h" # include "cmAddLinkOptionsCommand.h" # include "cmAuxSourceDirectoryCommand.h" @@ -112,52 +116,51 @@ void GetScriptingCommands(cmState* state) { - state->AddBuiltinCommand("break", new cmBreakCommand); - state->AddBuiltinCommand("cmake_minimum_required", - new cmCMakeMinimumRequired); - state->AddBuiltinCommand("cmake_policy", new cmCMakePolicyCommand); - state->AddBuiltinCommand("configure_file", new cmConfigureFileCommand); - state->AddBuiltinCommand("continue", new cmContinueCommand); - state->AddBuiltinCommand("exec_program", new cmExecProgramCommand); - state->AddBuiltinCommand("execute_process", new cmExecuteProcessCommand); - state->AddBuiltinCommand("file", new cmFileCommand); - state->AddBuiltinCommand("find_file", new cmFindFileCommand); - state->AddBuiltinCommand("find_library", new cmFindLibraryCommand); - state->AddBuiltinCommand("find_package", new cmFindPackageCommand); - state->AddBuiltinCommand("find_path", new cmFindPathCommand); - state->AddBuiltinCommand("find_program", new cmFindProgramCommand); - state->AddBuiltinCommand("foreach", new cmForEachCommand); - state->AddBuiltinCommand("function", new cmFunctionCommand); - state->AddBuiltinCommand("get_cmake_property", - new cmGetCMakePropertyCommand); + 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", + cm::make_unique<cmFindLibraryCommand>()); + state->AddBuiltinCommand("find_package", + cm::make_unique<cmFindPackageCommand>()); + state->AddBuiltinCommand("find_path", cm::make_unique<cmFindPathCommand>()); + state->AddBuiltinCommand("find_program", + cm::make_unique<cmFindProgramCommand>()); + state->AddBuiltinCommand("foreach", cmForEachCommand); + state->AddBuiltinCommand("function", cmFunctionCommand); + state->AddBuiltinCommand("get_cmake_property", cmGetCMakePropertyCommand); state->AddBuiltinCommand("get_directory_property", - new cmGetDirectoryPropertyCommand); + cmGetDirectoryPropertyCommand); state->AddBuiltinCommand("get_filename_component", - new cmGetFilenameComponentCommand); - state->AddBuiltinCommand("get_property", new cmGetPropertyCommand); - state->AddBuiltinCommand("if", new cmIfCommand); - state->AddBuiltinCommand("include", new cmIncludeCommand); - state->AddBuiltinCommand("include_guard", new cmIncludeGuardCommand); - state->AddBuiltinCommand("list", new cmListCommand); - state->AddBuiltinCommand("macro", new cmMacroCommand); - state->AddBuiltinCommand("make_directory", new cmMakeDirectoryCommand); - state->AddBuiltinCommand("mark_as_advanced", new cmMarkAsAdvancedCommand); - state->AddBuiltinCommand("math", new cmMathCommand); - state->AddBuiltinCommand("message", new cmMessageCommand); - state->AddBuiltinCommand("option", new cmOptionCommand); - state->AddBuiltinCommand("cmake_parse_arguments", - new cmParseArgumentsCommand); - state->AddBuiltinCommand("return", new cmReturnCommand); - state->AddBuiltinCommand("separate_arguments", - new cmSeparateArgumentsCommand); - state->AddBuiltinCommand("set", new cmSetCommand); + cmGetFilenameComponentCommand); + state->AddBuiltinCommand("get_property", cmGetPropertyCommand); + state->AddBuiltinCommand("if", cmIfCommand); + 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", cmSeparateArgumentsCommand); + state->AddBuiltinCommand("set", cmSetCommand); state->AddBuiltinCommand("set_directory_properties", - new cmSetDirectoryPropertiesCommand); - state->AddBuiltinCommand("set_property", new cmSetPropertyCommand); - state->AddBuiltinCommand("site_name", new cmSiteNameCommand); - state->AddBuiltinCommand("string", new cmStringCommand); - state->AddBuiltinCommand("unset", new cmUnsetCommand); - state->AddBuiltinCommand("while", new cmWhileCommand); + 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( "else", @@ -194,18 +197,19 @@ void GetScriptingCommands(cmState* state) "WHILE ENDWHILE structure. Or its arguments did not " "match the opening WHILE command."); -#if defined(CMAKE_BUILD_WITH_CMAKE) +#if !defined(CMAKE_BOOTSTRAP) state->AddBuiltinCommand("cmake_host_system_information", - new cmCMakeHostSystemInformationCommand); - state->AddBuiltinCommand("remove", new cmRemoveCommand); - state->AddBuiltinCommand("variable_watch", new cmVariableWatchCommand); - state->AddBuiltinCommand("write_file", new cmWriteFileCommand); + cmCMakeHostSystemInformationCommand); + state->AddBuiltinCommand("remove", cmRemoveCommand); + state->AddBuiltinCommand("variable_watch", cmVariableWatchCommand); + state->AddBuiltinCommand("write_file", cmWriteFileCommand); state->AddDisallowedCommand( - "build_name", new cmBuildNameCommand, cmPolicies::CMP0036, + "build_name", cmBuildNameCommand, cmPolicies::CMP0036, "The build_name command should not be called; see CMP0036."); state->AddDisallowedCommand( - "use_mangled_mesa", new cmUseMangledMesaCommand, cmPolicies::CMP0030, + "use_mangled_mesa", cm::make_unique<cmUseMangledMesaCommand>(), + cmPolicies::CMP0030, "The use_mangled_mesa command should not be called; see CMP0030."); #endif @@ -213,101 +217,122 @@ void GetScriptingCommands(cmState* state) void GetProjectCommands(cmState* state) { - state->AddBuiltinCommand("add_custom_command", - new cmAddCustomCommandCommand); - state->AddBuiltinCommand("add_custom_target", new cmAddCustomTargetCommand); - state->AddBuiltinCommand("add_definitions", new cmAddDefinitionsCommand); - state->AddBuiltinCommand("add_dependencies", new cmAddDependenciesCommand); - state->AddBuiltinCommand("add_executable", new cmAddExecutableCommand); - state->AddBuiltinCommand("add_library", new cmAddLibraryCommand); - state->AddBuiltinCommand("add_subdirectory", new cmAddSubDirectoryCommand); - state->AddBuiltinCommand("add_test", new cmAddTestCommand); - state->AddBuiltinCommand("build_command", new cmBuildCommand); + state->AddBuiltinCommand("add_custom_command", cmAddCustomCommandCommand); + state->AddBuiltinCommand("add_custom_target", cmAddCustomTargetCommand); + state->AddBuiltinCommand("add_definitions", cmAddDefinitionsCommand); + state->AddBuiltinCommand("add_dependencies", cmAddDependenciesCommand); + state->AddBuiltinCommand("add_executable", cmAddExecutableCommand); + state->AddBuiltinCommand("add_library", cmAddLibraryCommand); + state->AddBuiltinCommand("add_subdirectory", cmAddSubDirectoryCommand); + state->AddBuiltinCommand("add_test", cmAddTestCommand); + state->AddBuiltinCommand("build_command", cm::make_unique<cmBuildCommand>()); state->AddBuiltinCommand("create_test_sourcelist", - new cmCreateTestSourceList); - state->AddBuiltinCommand("define_property", new cmDefinePropertyCommand); - state->AddBuiltinCommand("enable_language", new cmEnableLanguageCommand); - state->AddBuiltinCommand("enable_testing", new cmEnableTestingCommand); + cm::make_unique<cmCreateTestSourceList>()); + state->AddBuiltinCommand("define_property", + cm::make_unique<cmDefinePropertyCommand>()); + state->AddBuiltinCommand("enable_language", + cm::make_unique<cmEnableLanguageCommand>()); + state->AddBuiltinCommand("enable_testing", cmEnableTestingCommand); state->AddBuiltinCommand("get_source_file_property", - new cmGetSourceFilePropertyCommand); + cm::make_unique<cmGetSourceFilePropertyCommand>()); state->AddBuiltinCommand("get_target_property", - new cmGetTargetPropertyCommand); - state->AddBuiltinCommand("get_test_property", new cmGetTestPropertyCommand); + cm::make_unique<cmGetTargetPropertyCommand>()); + state->AddBuiltinCommand("get_test_property", + cm::make_unique<cmGetTestPropertyCommand>()); state->AddBuiltinCommand("include_directories", - new cmIncludeDirectoryCommand); - state->AddBuiltinCommand("include_regular_expression", - new cmIncludeRegularExpressionCommand); - state->AddBuiltinCommand("install", new cmInstallCommand); - state->AddBuiltinCommand("install_files", new cmInstallFilesCommand); - state->AddBuiltinCommand("install_targets", new cmInstallTargetsCommand); - state->AddBuiltinCommand("link_directories", new cmLinkDirectoriesCommand); - state->AddBuiltinCommand("project", new cmProjectCommand); - state->AddBuiltinCommand("set_source_files_properties", - new cmSetSourceFilesPropertiesCommand); + cm::make_unique<cmIncludeDirectoryCommand>()); + state->AddBuiltinCommand( + "include_regular_expression", + cm::make_unique<cmIncludeRegularExpressionCommand>()); + state->AddBuiltinCommand("install", cm::make_unique<cmInstallCommand>()); + state->AddBuiltinCommand("install_files", + cm::make_unique<cmInstallFilesCommand>()); + state->AddBuiltinCommand("install_targets", + cm::make_unique<cmInstallTargetsCommand>()); + state->AddBuiltinCommand("link_directories", + cm::make_unique<cmLinkDirectoriesCommand>()); + state->AddBuiltinCommand("project", cm::make_unique<cmProjectCommand>()); + state->AddBuiltinCommand( + "set_source_files_properties", + cm::make_unique<cmSetSourceFilesPropertiesCommand>()); state->AddBuiltinCommand("set_target_properties", - new cmSetTargetPropertiesCommand); + cm::make_unique<cmSetTargetPropertiesCommand>()); state->AddBuiltinCommand("set_tests_properties", - new cmSetTestsPropertiesCommand); - state->AddBuiltinCommand("subdirs", new cmSubdirCommand); - state->AddBuiltinCommand("target_compile_definitions", - new cmTargetCompileDefinitionsCommand); + cm::make_unique<cmSetTestsPropertiesCommand>()); + state->AddBuiltinCommand("subdirs", cm::make_unique<cmSubdirCommand>()); + state->AddBuiltinCommand( + "target_compile_definitions", + cm::make_unique<cmTargetCompileDefinitionsCommand>()); state->AddBuiltinCommand("target_compile_features", - new cmTargetCompileFeaturesCommand); + cm::make_unique<cmTargetCompileFeaturesCommand>()); state->AddBuiltinCommand("target_compile_options", - new cmTargetCompileOptionsCommand); - state->AddBuiltinCommand("target_include_directories", - new cmTargetIncludeDirectoriesCommand); + cm::make_unique<cmTargetCompileOptionsCommand>()); + state->AddBuiltinCommand( + "target_include_directories", + cm::make_unique<cmTargetIncludeDirectoriesCommand>()); state->AddBuiltinCommand("target_link_libraries", - new cmTargetLinkLibrariesCommand); - state->AddBuiltinCommand("target_sources", new cmTargetSourcesCommand); - state->AddBuiltinCommand("try_compile", new cmTryCompileCommand); - state->AddBuiltinCommand("try_run", new cmTryRunCommand); + cm::make_unique<cmTargetLinkLibrariesCommand>()); + state->AddBuiltinCommand("target_sources", + cm::make_unique<cmTargetSourcesCommand>()); + state->AddBuiltinCommand("try_compile", + cm::make_unique<cmTryCompileCommand>()); + state->AddBuiltinCommand("try_run", cm::make_unique<cmTryRunCommand>()); -#if defined(CMAKE_BUILD_WITH_CMAKE) +#if !defined(CMAKE_BOOTSTRAP) state->AddBuiltinCommand("add_compile_definitions", - new cmAddCompileDefinitionsCommand); - state->AddBuiltinCommand("add_compile_options", - new cmAddCompileOptionsCommand); + cmAddCompileDefinitionsCommand); + state->AddBuiltinCommand("add_compile_options", cmAddCompileOptionsCommand); state->AddBuiltinCommand("aux_source_directory", - new cmAuxSourceDirectoryCommand); - state->AddBuiltinCommand("export", new cmExportCommand); - state->AddBuiltinCommand("fltk_wrap_ui", new cmFLTKWrapUICommand); - state->AddBuiltinCommand("include_external_msproject", - new cmIncludeExternalMSProjectCommand); - state->AddBuiltinCommand("install_programs", new cmInstallProgramsCommand); - state->AddBuiltinCommand("add_link_options", new cmAddLinkOptionsCommand); - state->AddBuiltinCommand("link_libraries", new cmLinkLibrariesCommand); + cmAuxSourceDirectoryCommand); + state->AddBuiltinCommand("export", cm::make_unique<cmExportCommand>()); + state->AddBuiltinCommand("fltk_wrap_ui", + cm::make_unique<cmFLTKWrapUICommand>()); + state->AddBuiltinCommand( + "include_external_msproject", + cm::make_unique<cmIncludeExternalMSProjectCommand>()); + state->AddBuiltinCommand("install_programs", + cm::make_unique<cmInstallProgramsCommand>()); + state->AddBuiltinCommand("add_link_options", cmAddLinkOptionsCommand); + state->AddBuiltinCommand("link_libraries", + cm::make_unique<cmLinkLibrariesCommand>()); state->AddBuiltinCommand("target_link_options", - new cmTargetLinkOptionsCommand); + cm::make_unique<cmTargetLinkOptionsCommand>()); state->AddBuiltinCommand("target_link_directories", - new cmTargetLinkDirectoriesCommand); - state->AddBuiltinCommand("load_cache", new cmLoadCacheCommand); - state->AddBuiltinCommand("qt_wrap_cpp", new cmQTWrapCPPCommand); - state->AddBuiltinCommand("qt_wrap_ui", new cmQTWrapUICommand); + cm::make_unique<cmTargetLinkDirectoriesCommand>()); + state->AddBuiltinCommand("load_cache", + cm::make_unique<cmLoadCacheCommand>()); + state->AddBuiltinCommand("qt_wrap_cpp", + cm::make_unique<cmQTWrapCPPCommand>()); + state->AddBuiltinCommand("qt_wrap_ui", cm::make_unique<cmQTWrapUICommand>()); state->AddBuiltinCommand("remove_definitions", - new cmRemoveDefinitionsCommand); - state->AddBuiltinCommand("source_group", new cmSourceGroupCommand); + cm::make_unique<cmRemoveDefinitionsCommand>()); + state->AddBuiltinCommand("source_group", + cm::make_unique<cmSourceGroupCommand>()); state->AddDisallowedCommand( - "export_library_dependencies", new cmExportLibraryDependenciesCommand, - cmPolicies::CMP0033, + "export_library_dependencies", + cm::make_unique<cmExportLibraryDependenciesCommand>(), cmPolicies::CMP0033, "The export_library_dependencies command should not be called; " "see CMP0033."); state->AddDisallowedCommand( - "load_command", new cmLoadCommandCommand, cmPolicies::CMP0031, + "load_command", cm::make_unique<cmLoadCommandCommand>(), + cmPolicies::CMP0031, "The load_command command should not be called; see CMP0031."); state->AddDisallowedCommand( - "output_required_files", new cmOutputRequiredFilesCommand, + "output_required_files", cm::make_unique<cmOutputRequiredFilesCommand>(), cmPolicies::CMP0032, "The output_required_files command should not be called; see CMP0032."); state->AddDisallowedCommand( - "subdir_depends", new cmSubdirDependsCommand, cmPolicies::CMP0029, + "subdir_depends", cm::make_unique<cmSubdirDependsCommand>(), + cmPolicies::CMP0029, "The subdir_depends command should not be called; see CMP0029."); state->AddDisallowedCommand( - "utility_source", new cmUtilitySourceCommand, cmPolicies::CMP0034, + "utility_source", cm::make_unique<cmUtilitySourceCommand>(), + cmPolicies::CMP0034, "The utility_source command should not be called; see CMP0034."); state->AddDisallowedCommand( - "variable_requires", new cmVariableRequiresCommand, cmPolicies::CMP0035, + "variable_requires", cm::make_unique<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 66250f3..49db505 100644 --- a/Source/cmCommonTargetGenerator.cxx +++ b/Source/cmCommonTargetGenerator.cxx @@ -6,7 +6,6 @@ #include <sstream> #include <utility> -#include "cmAlgorithms.h" #include "cmComputeLinkInformation.h" #include "cmGeneratorTarget.h" #include "cmGlobalCommonGenerator.h" @@ -17,6 +16,7 @@ #include "cmOutputConverter.h" #include "cmSourceFile.h" #include "cmStateTypes.h" +#include "cmStringAlgorithms.h" cmCommonTargetGenerator::cmCommonTargetGenerator(cmGeneratorTarget* gt) : GeneratorTarget(gt) @@ -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 186deb6..a39425c 100644 --- a/Source/cmComputeLinkDepends.cxx +++ b/Source/cmComputeLinkDepends.cxx @@ -11,7 +11,7 @@ #include "cmMakefile.h" #include "cmRange.h" #include "cmStateTypes.h" -#include "cmSystemTools.h" +#include "cmStringAlgorithms.h" #include "cmTarget.h" #include "cmake.h" @@ -23,6 +23,8 @@ #include <string.h> #include <utility> +#include "cm_memory.hxx" + /* This file computes an ordered list of link items to use when linking a @@ -202,7 +204,6 @@ cmComputeLinkDepends::cmComputeLinkDepends(const cmGeneratorTarget* target, cmComputeLinkDepends::~cmComputeLinkDepends() { cmDeleteAll(this->InferredDependSets); - delete this->CCG; } void cmComputeLinkDepends::SetOldLinkDirMode(bool b) @@ -318,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 }; @@ -436,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; - cmSystemTools::ExpandListArgument(value, deplist); + std::vector<std::string> deplist = cmExpandedList(value); // Look for entries meant for this configuration. std::vector<cmLinkItem> actual_libs; @@ -460,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; @@ -632,7 +630,8 @@ void cmComputeLinkDepends::OrderLinkEntires() // the same order in which the items were originally discovered in // the BFS. This should preserve the original order when no // constraints disallow it. - this->CCG = new cmComputeComponentGraph(this->EntryConstraintGraph); + this->CCG = + cm::make_unique<cmComputeComponentGraph>(this->EntryConstraintGraph); // The component graph is guaranteed to be acyclic. Start a DFS // from every entry to compute a topological order for the diff --git a/Source/cmComputeLinkDepends.h b/Source/cmComputeLinkDepends.h index dfaaf8b..839c27a 100644 --- a/Source/cmComputeLinkDepends.h +++ b/Source/cmComputeLinkDepends.h @@ -10,6 +10,7 @@ #include "cmTargetLinkLibraryType.h" #include <map> +#include <memory> #include <queue> #include <set> #include <string> @@ -137,7 +138,7 @@ private: std::set<int> Entries; }; std::map<int, PendingComponent> PendingComponents; - cmComputeComponentGraph* CCG; + std::unique_ptr<cmComputeComponentGraph> CCG; std::vector<int> FinalLinkOrder; void DisplayComponents(); void VisitComponent(unsigned int c); diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx index 44d8615..880d5c0 100644 --- a/Source/cmComputeLinkInformation.cxx +++ b/Source/cmComputeLinkInformation.cxx @@ -14,6 +14,7 @@ #include "cmPolicies.h" #include "cmState.h" #include "cmStateTypes.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmTarget.h" #include "cmake.h" @@ -268,10 +269,6 @@ cmComputeLinkInformation::cmComputeLinkInformation( return; } - // Check whether we should use an import library for linking a target. - this->UseImportLibrary = - this->Makefile->IsDefinitionSet("CMAKE_IMPORT_LIBRARY_SUFFIX"); - // Check whether we should skip dependencies on shared library files. this->LinkDependsNoShared = this->Target->GetPropertyAsBool("LINK_DEPENDS_NO_SHARED"); @@ -280,17 +277,21 @@ cmComputeLinkInformation::cmComputeLinkInformation( // to use when creating a plugin (module) that obtains symbols from // the program that will load it. this->LoaderFlag = nullptr; - if (!this->UseImportLibrary && + 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); } // Get options needed to link libraries. - this->LibLinkFlag = - this->Makefile->GetSafeDefinition("CMAKE_LINK_LIBRARY_FLAG"); + if (const char* flag = this->Makefile->GetDefinition( + "CMAKE_" + this->LinkLanguage + "_LINK_LIBRARY_FLAG")) { + this->LibLinkFlag = flag; + } else { + this->LibLinkFlag = + this->Makefile->GetSafeDefinition("CMAKE_LINK_LIBRARY_FLAG"); + } this->LibLinkFileFlag = this->Makefile->GetSafeDefinition("CMAKE_LINK_LIBRARY_FILE_FLAG"); this->LibLinkSuffix = @@ -302,11 +303,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); @@ -316,19 +314,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); } @@ -479,7 +473,7 @@ bool cmComputeLinkInformation::Compute() // Restore the target link type so the correct system runtime // libraries are found. const char* lss = this->Target->GetProperty("LINK_SEARCH_END_STATIC"); - if (cmSystemTools::IsOn(lss)) { + if (cmIsOn(lss)) { this->SetCurrentLinkType(LinkStatic); } else { this->SetCurrentLinkType(this->StartLinkType); @@ -493,9 +487,7 @@ bool cmComputeLinkInformation::Compute() std::set<cmGeneratorTarget const*> const& wrongItems = cld.GetOldWrongConfigItems(); for (cmGeneratorTarget const* tgt : wrongItems) { - bool implib = (this->UseImportLibrary && - (tgt->GetType() == cmStateEnums::SHARED_LIBRARY)); - cmStateEnums::ArtifactType artifact = implib + cmStateEnums::ArtifactType artifact = tgt->HasImportLibrary(this->Config) ? cmStateEnums::ImportLibraryArtifact : cmStateEnums::RuntimeBinaryArtifact; this->OldLinkDirItems.push_back( @@ -547,14 +539,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; - cmSystemTools::ExpandListArgument(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); } } @@ -562,12 +551,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; - cmSystemTools::ExpandListArgument(dirs, dirsVec); + std::vector<std::string> dirsVec = cmExpandedList(dirs); this->OrderLinkerSearchPath->AddLanguageDirectories(dirsVec); } } @@ -578,7 +564,7 @@ void cmComputeLinkInformation::AddItem(std::string const& item, // Compute the proper name to use to link this library. const std::string& config = this->Config; bool impexe = (tgt && tgt->IsExecutableWithExports()); - if (impexe && !this->UseImportLibrary && !this->LoaderFlag) { + if (impexe && !tgt->HasImportLibrary(config) && !this->LoaderFlag) { // Skip linking to executables on platforms with no import // libraries or loader flags. return; @@ -592,7 +578,7 @@ void cmComputeLinkInformation::AddItem(std::string const& item, // platform. Add it now. std::string linkItem; linkItem = this->LoaderFlag; - cmStateEnums::ArtifactType artifact = this->UseImportLibrary + cmStateEnums::ArtifactType artifact = tgt->HasImportLibrary(config) ? cmStateEnums::ImportLibraryArtifact : cmStateEnums::RuntimeBinaryArtifact; @@ -616,15 +602,21 @@ void cmComputeLinkInformation::AddItem(std::string const& item, // Its object-files should already have been extracted for linking. } else { // Decide whether to use an import library. - bool implib = - (this->UseImportLibrary && - (impexe || tgt->GetType() == cmStateEnums::SHARED_LIBRARY)); - cmStateEnums::ArtifactType artifact = implib + cmStateEnums::ArtifactType artifact = tgt->HasImportLibrary(config) ? cmStateEnums::ImportLibraryArtifact : cmStateEnums::RuntimeBinaryArtifact; // Pass the full path to the target file. std::string lib = tgt->GetFullPath(config, artifact, true); + if (tgt->Target->IsAIX() && cmHasLiteralSuffix(lib, "-NOTFOUND") && + artifact == cmStateEnums::ImportLibraryArtifact) { + // This is an imported executable on AIX that has ENABLE_EXPORTS + // but not IMPORTED_IMPLIB. CMake used to produce and accept such + // imported executables on AIX before we taught it to use linker + // import files. For compatibility, simply skip linking to this + // executable as we did before. It works with runtime linking. + return; + } if (!this->LinkDependsNoShared || tgt->GetType() != cmStateEnums::SHARED_LIBRARY) { this->Depends.push_back(lib); @@ -694,7 +686,7 @@ void cmComputeLinkInformation::AddSharedDepItem(std::string const& item, // linked will be able to find it. std::string lib; if (tgt) { - cmStateEnums::ArtifactType artifact = this->UseImportLibrary + cmStateEnums::ArtifactType artifact = tgt->HasImportLibrary(this->Config) ? cmStateEnums::ImportLibraryArtifact : cmStateEnums::RuntimeBinaryArtifact; lib = tgt->GetFullPath(this->Config, artifact); @@ -754,19 +746,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); } @@ -782,7 +770,7 @@ void cmComputeLinkInformation::ComputeLinkTypeInfo() // Lookup the starting link type from the target (linked statically?). const char* lss = this->Target->GetProperty("LINK_SEARCH_START_STATIC"); - this->StartLinkType = cmSystemTools::IsOn(lss) ? LinkStatic : LinkShared; + this->StartLinkType = cmIsOn(lss) ? LinkStatic : LinkShared; this->CurrentLinkType = this->StartLinkType; } @@ -805,16 +793,14 @@ void cmComputeLinkInformation::ComputeItemParserInfo() LinkUnknown); if (const char* linkSuffixes = mf->GetDefinition("CMAKE_EXTRA_LINK_EXTENSIONS")) { - std::vector<std::string> linkSuffixVec; - cmSystemTools::ExpandListArgument(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; - cmSystemTools::ExpandListArgument(sharedSuffixes, sharedSuffixVec); + std::vector<std::string> sharedSuffixVec = cmExpandedList(sharedSuffixes); for (std::string const& i : sharedSuffixVec) { this->AddLinkExtension(i.c_str(), LinkShared); } @@ -842,8 +828,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 @@ -851,9 +836,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 @@ -990,16 +974,11 @@ void cmComputeLinkInformation::AddTargetItem(std::string const& item, return; } - // If this platform wants a flag before the full path, add it. - if (!this->LibLinkFileFlag.empty()) { - this->Items.emplace_back(this->LibLinkFileFlag, false); - } - // 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,16 +1031,11 @@ 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); } - // If this platform wants a flag before the full path, add it. - if (!this->LibLinkFileFlag.empty()) { - this->Items.emplace_back(this->LibLinkFileFlag, false); - } - // Now add the full path to the library. this->Items.emplace_back(item, true); } @@ -1077,7 +1051,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; @@ -1219,9 +1193,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 @@ -1243,12 +1215,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); @@ -1293,16 +1260,15 @@ void cmComputeLinkInformation::ComputeFrameworkInfo() // Get platform-wide implicit directories. if (const char* implicitLinks = this->Makefile->GetDefinition( "CMAKE_PLATFORM_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES")) { - cmSystemTools::ExpandListArgument(implicitLinks, implicitDirVec); + cmExpandList(implicitLinks, implicitDirVec); } // 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)) { - cmSystemTools::ExpandListArgument(implicitDirs, implicitDirVec); + cmExpandList(implicitDirs, implicitDirVec); } this->FrameworkPathsEmmitted.insert(implicitDirVec.begin(), @@ -1372,8 +1338,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; @@ -1521,7 +1486,7 @@ void cmComputeLinkInformation::LoadImplicitLinkInfo() // Get platform-wide implicit directories. if (const char* implicitLinks = (this->Makefile->GetDefinition( "CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES"))) { - cmSystemTools::ExpandListArgument(implicitLinks, implicitDirVec); + cmExpandList(implicitLinks, implicitDirVec); } // Append library architecture to all implicit platform directories @@ -1534,12 +1499,11 @@ 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)) { - cmSystemTools::ExpandListArgument(implicitDirs, implicitDirVec); + cmExpandList(implicitDirs, implicitDirVec); } // Store implicit link directories. @@ -1547,12 +1511,11 @@ 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)) { - cmSystemTools::ExpandListArgument(implicitLibs, implicitLibVec); + cmExpandList(implicitLibs, implicitLibVec); } // Store implicit link libraries. @@ -1567,7 +1530,7 @@ void cmComputeLinkInformation::LoadImplicitLinkInfo() // Get platform specific rpath link directories if (const char* rpathDirs = (this->Makefile->GetDefinition("CMAKE_PLATFORM_RUNTIME_PATH"))) { - cmSystemTools::ExpandListArgument(rpathDirs, this->RuntimeLinkDirs); + cmExpandList(rpathDirs, this->RuntimeLinkDirs); } } @@ -1673,8 +1636,7 @@ static void cmCLI_ExpandListUnique(const char* str, std::vector<std::string>& out, std::set<std::string>& emitted) { - std::vector<std::string> tmp; - cmSystemTools::ExpandListArgument(str, tmp); + std::vector<std::string> tmp = cmExpandedList(str); for (std::string const& i : tmp) { if (emitted.insert(i).second) { out.push_back(i); @@ -1695,7 +1657,7 @@ void cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs, (for_install || this->Target->GetPropertyAsBool("BUILD_WITH_INSTALL_RPATH")); bool use_install_rpath = - (outputRuntime && this->Target->HaveInstallTreeRPATH() && + (outputRuntime && this->Target->HaveInstallTreeRPATH(this->Config) && linking_for_install); bool use_build_rpath = (outputRuntime && this->Target->HaveBuildTreeRPATH(this->Config) && @@ -1715,15 +1677,17 @@ void cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs, // Construct the RPATH. std::set<std::string> emitted; if (use_install_rpath) { - const char* install_rpath = this->Target->GetProperty("INSTALL_RPATH"); - cmCLI_ExpandListUnique(install_rpath, runtimeDirs, emitted); + std::string install_rpath; + this->Target->GetInstallRPATH(this->Config, install_rpath); + cmCLI_ExpandListUnique(install_rpath.c_str(), runtimeDirs, emitted); } if (use_build_rpath) { // Add directories explicitly specified by user - if (const char* build_rpath = this->Target->GetProperty("BUILD_RPATH")) { + std::string build_rpath; + if (this->Target->GetBuildRPATH(this->Config, build_rpath)) { // This will not resolve entries to use $ORIGIN, the user is expected to // do that if necessary. - cmCLI_ExpandListUnique(build_rpath, runtimeDirs, emitted); + cmCLI_ExpandListUnique(build_rpath.c_str(), runtimeDirs, emitted); } } if (use_build_rpath || use_link_rpath) { @@ -1751,9 +1715,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 @@ -1762,7 +1724,7 @@ void cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs, cmSystemTools::IsSubDirectory(d, topBinaryDir)) { d = cmSystemTools::RelativePath(targetOutputDir, d); if (!d.empty()) { - d = originToken + "/" + d; + d = cmStrCat(originToken, "/", d); } else { d = originToken; } @@ -1784,9 +1746,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/cmComputeLinkInformation.h b/Source/cmComputeLinkInformation.h index 863639c..784d3fa 100644 --- a/Source/cmComputeLinkInformation.h +++ b/Source/cmComputeLinkInformation.h @@ -56,6 +56,11 @@ public: std::string GetChrpathString() const; std::set<cmGeneratorTarget const*> const& GetSharedLibrariesLinked() const; + std::string const& GetLibLinkFileFlag() const + { + return this->LibLinkFileFlag; + } + std::string const& GetRPathLinkFlag() const { return this->RPathLinkFlag; } std::string GetRPathLinkString() const; @@ -179,7 +184,6 @@ private: bool OldLinkDirMode; bool OpenBSD; bool LinkDependsNoShared; - bool UseImportLibrary; bool RuntimeUseChrpath; bool NoSONameUsesPath; bool LinkWithRuntimePath; diff --git a/Source/cmConditionEvaluator.cxx b/Source/cmConditionEvaluator.cxx index e7e91c1..21df278 100644 --- a/Source/cmConditionEvaluator.cxx +++ b/Source/cmConditionEvaluator.cxx @@ -3,7 +3,7 @@ #include "cmConditionEvaluator.h" #include "cmsys/RegularExpression.hxx" -#include <algorithm> +#include <functional> #include <sstream> #include <stdio.h> #include <stdlib.h> @@ -14,10 +14,10 @@ #include "cmMakefile.h" #include "cmMessageType.h" #include "cmState.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmake.h" -class cmCommand; class cmTest; static std::string const keyAND = "AND"; @@ -219,10 +219,10 @@ bool cmConditionEvaluator::GetBooleanValue( } // Check named constants. - if (cmSystemTools::IsOn(arg.c_str())) { + if (cmIsOn(arg.GetValue())) { return true; } - if (cmSystemTools::IsOff(arg.c_str())) { + if (cmIsOff(arg.GetValue())) { return false; } @@ -238,7 +238,7 @@ bool cmConditionEvaluator::GetBooleanValue( // Check definition. const char* def = this->GetDefinitionIfUnquoted(arg); - return !cmSystemTools::IsOff(def); + return !cmIsOff(def); } //========================================================================= @@ -255,14 +255,14 @@ bool cmConditionEvaluator::GetBooleanValueOld( return true; } const char* def = this->GetDefinitionIfUnquoted(arg); - return !cmSystemTools::IsOff(def); + return !cmIsOff(def); } // Old GetVariableOrNumber behavior. const char* def = this->GetDefinitionIfUnquoted(arg); if (!def && atoi(arg.c_str())) { def = arg.c_str(); } - return !cmSystemTools::IsOff(def); + return !cmIsOff(def); } //========================================================================= @@ -452,7 +452,7 @@ bool cmConditionEvaluator::HandleLevel1(cmArgumentList& newArgs, std::string&, } // does a command exist if (this->IsKeyword(keyCOMMAND, *arg) && argP1 != newArgs.end()) { - cmCommand* command = + cmState::Command command = this->Makefile.GetState()->GetCommand(argP1->c_str()); this->HandlePredicate(command != nullptr, reducible, arg, newArgs, argP1, argP2); @@ -668,10 +668,9 @@ bool cmConditionEvaluator::HandleLevel2(cmArgumentList& newArgs, def2 = this->Makefile.GetDefinition(argP2->GetValue()); if (def2) { - std::vector<std::string> list; - cmSystemTools::ExpandListArgument(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 5603c50..c7f95b8 100644 --- a/Source/cmConfigureFileCommand.h +++ b/Source/cmConfigureFileCommand.h @@ -8,33 +8,8 @@ #include <string> #include <vector> -#include "cmCommand.h" -#include "cmNewLineStyle.h" - class cmExecutionStatus; -class cmConfigureFileCommand : public cmCommand -{ -public: - cmCommand* Clone() override { return new 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 d383d1d..ff903aa 100644 --- a/Source/cmContinueCommand.h +++ b/Source/cmContinueCommand.h @@ -8,29 +8,14 @@ #include <string> #include <vector> -#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. - */ - cmCommand* Clone() override { return new 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 f12ef0b..3687056 100644 --- a/Source/cmCoreTryCompile.cxx +++ b/Source/cmCoreTryCompile.cxx @@ -9,7 +9,6 @@ #include <string.h> #include <utility> -#include "cmAlgorithms.h" #include "cmExportTryCompileFileGenerator.h" #include "cmGlobalGenerator.h" #include "cmMakefile.h" @@ -17,6 +16,7 @@ #include "cmOutputConverter.h" #include "cmPolicies.h" #include "cmState.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmTarget.h" #include "cmVersion.h" @@ -234,11 +234,11 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv, } else if (doing == DoingCMakeFlags) { cmakeFlags.push_back(argv[i]); } else if (doing == DoingCompileDefinitions) { - cmSystemTools::ExpandListArgument(argv[i], compileDefs); + cmExpandList(argv[i], compileDefs); } else if (doing == DoingLinkOptions) { linkOptions.push_back(argv[i]); } else if (doing == DoingLinkLibraries) { - libsToLink += "\"" + cmSystemTools::TrimWhitespace(argv[i]) + "\" "; + libsToLink += "\"" + cmTrimWhitespace(argv[i]) + "\" "; if (cmTarget* tgt = this->Makefile->FindTargetToUse(argv[i])) { switch (tgt->GetType()) { case cmStateEnums::SHARED_LIBRARY: @@ -411,8 +411,7 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv, // compute the binary dir when TRY_COMPILE is called with a src file // signature if (this->SrcFileSignature) { - this->BinaryDirectory += "/CMakeFiles"; - this->BinaryDirectory += "/CMakeTmp"; + this->BinaryDirectory += "/CMakeFiles/CMakeTmp"; } else { // only valid for srcfile signatures if (!compileDefs.empty()) { @@ -514,7 +513,7 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv, for (std::string const& li : testLangs) { projectLangs += " " + li; std::string rulesOverrideBase = "CMAKE_USER_MAKE_RULES_OVERRIDE"; - std::string rulesOverrideLang = rulesOverrideBase + "_" + li; + std::string rulesOverrideLang = cmStrCat(rulesOverrideBase, "_", li); if (const char* rulesOverridePath = this->Makefile->GetDefinition(rulesOverrideLang)) { fprintf(fout, "set(%s \"%s\")\n", rulesOverrideLang.c_str(), @@ -574,7 +573,8 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv, std::string const cfg = !tcConfig.empty() ? cmSystemTools::UpperCase(tcConfig) : cfgDefault; for (std::string const& li : testLangs) { - std::string const langFlagsCfg = "CMAKE_" + li + "_FLAGS_" + cfg; + std::string const langFlagsCfg = + cmStrCat("CMAKE_", li, "_FLAGS_", cfg); const char* flagsCfg = this->Makefile->GetDefinition(langFlagsCfg); fprintf(fout, "set(%s %s)\n", langFlagsCfg.c_str(), cmOutputConverter::EscapeForCMake(flagsCfg ? flagsCfg : "") @@ -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; - cmSystemTools::ExpandListArgument(varListStr, varList); + std::vector<std::string> varList = cmExpandedList(varListStr); vars.insert(varList.begin(), varList.end()); } @@ -932,7 +931,7 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv, cmStateEnums::INTERNAL); if (!outputVariable.empty()) { - this->Makefile->AddDefinition(outputVariable, output.c_str()); + this->Makefile->AddDefinition(outputVariable, output); } if (this->SrcFileSignature) { @@ -961,8 +960,7 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv, } if (!copyFileError.empty()) { - this->Makefile->AddDefinition(copyFileError, - copyFileErrorMessage.c_str()); + this->Makefile->AddDefinition(copyFileError, copyFileErrorMessage); } } return res; @@ -1046,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; @@ -1065,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 b78493f..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(); @@ -125,16 +122,15 @@ bool cmCreateTestSourceList::InitialPass(std::vector<std::string> const& args, } if (!extraInclude.empty()) { this->Makefile->AddDefinition("CMAKE_TESTDRIVER_EXTRA_INCLUDES", - extraInclude.c_str()); + extraInclude); } if (!function.empty()) { - this->Makefile->AddDefinition("CMAKE_TESTDRIVER_ARGVC_FUNCTION", - function.c_str()); + this->Makefile->AddDefinition("CMAKE_TESTDRIVER_ARGVC_FUNCTION", function); } this->Makefile->AddDefinition("CMAKE_FORWARD_DECLARE_TESTS", - forwardDeclareCode.c_str()); + forwardDeclareCode); this->Makefile->AddDefinition("CMAKE_FUNCTION_TABLE_ENTIRES", - functionMapCode.c_str()); + functionMapCode); bool res = true; if (!this->Makefile->ConfigureFile(configFile, driver, false, true, false)) { res = false; @@ -154,6 +150,6 @@ bool cmCreateTestSourceList::InitialPass(std::vector<std::string> const& args, sourceListValue += *i; } - this->Makefile->AddDefinition(sourceList, sourceListValue.c_str()); + this->Makefile->AddDefinition(sourceList, sourceListValue); return res; } diff --git a/Source/cmCreateTestSourceList.h b/Source/cmCreateTestSourceList.h index 005b32c..5aa6af4 100644 --- a/Source/cmCreateTestSourceList.h +++ b/Source/cmCreateTestSourceList.h @@ -8,6 +8,8 @@ #include <string> #include <vector> +#include "cm_memory.hxx" + #include "cmCommand.h" class cmExecutionStatus; @@ -23,7 +25,10 @@ public: /** * This is a virtual constructor for the command. */ - cmCommand* Clone() override { return new cmCreateTestSourceList; } + std::unique_ptr<cmCommand> Clone() override + { + return cm::make_unique<cmCreateTestSourceList>(); + } /** * This is called when the command is first encountered in diff --git a/Source/cmCryptoHash.cxx b/Source/cmCryptoHash.cxx index d914eb1..f9f9581 100644 --- a/Source/cmCryptoHash.cxx +++ b/Source/cmCryptoHash.cxx @@ -2,13 +2,11 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmCryptoHash.h" -#include "cmAlgorithms.h" #include "cm_kwiml.h" #include "cm_rhash.h" #include "cmsys/FStream.hxx" -#include <string.h> -#include <memory> // IWYU pragma: keep +#include "cm_memory.hxx" static unsigned int const cmCryptoHashAlgoToId[] = { /* clang-format needs this comment to break after the opening brace */ @@ -46,36 +44,36 @@ cmCryptoHash::~cmCryptoHash() rhash_free(this->CTX); } -std::unique_ptr<cmCryptoHash> cmCryptoHash::New(const char* algo) +std::unique_ptr<cmCryptoHash> cmCryptoHash::New(cm::string_view algo) { - if (strcmp(algo, "MD5") == 0) { + if (algo == "MD5") { return cm::make_unique<cmCryptoHash>(AlgoMD5); } - if (strcmp(algo, "SHA1") == 0) { + if (algo == "SHA1") { return cm::make_unique<cmCryptoHash>(AlgoSHA1); } - if (strcmp(algo, "SHA224") == 0) { + if (algo == "SHA224") { return cm::make_unique<cmCryptoHash>(AlgoSHA224); } - if (strcmp(algo, "SHA256") == 0) { + if (algo == "SHA256") { return cm::make_unique<cmCryptoHash>(AlgoSHA256); } - if (strcmp(algo, "SHA384") == 0) { + if (algo == "SHA384") { return cm::make_unique<cmCryptoHash>(AlgoSHA384); } - if (strcmp(algo, "SHA512") == 0) { + if (algo == "SHA512") { return cm::make_unique<cmCryptoHash>(AlgoSHA512); } - if (strcmp(algo, "SHA3_224") == 0) { + if (algo == "SHA3_224") { return cm::make_unique<cmCryptoHash>(AlgoSHA3_224); } - if (strcmp(algo, "SHA3_256") == 0) { + if (algo == "SHA3_256") { return cm::make_unique<cmCryptoHash>(AlgoSHA3_256); } - if (strcmp(algo, "SHA3_384") == 0) { + if (algo == "SHA3_384") { return cm::make_unique<cmCryptoHash>(AlgoSHA3_384); } - if (strcmp(algo, "SHA3_512") == 0) { + if (algo == "SHA3_512") { return cm::make_unique<cmCryptoHash>(AlgoSHA3_512); } return std::unique_ptr<cmCryptoHash>(nullptr); @@ -106,6 +104,7 @@ std::string cmCryptoHash::ByteHashToString( '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; std::string res; + res.reserve(hash.size() * 2); for (unsigned char v : hash) { res.push_back(hex[v >> 4]); res.push_back(hex[v & 0xF]); @@ -113,12 +112,10 @@ std::string cmCryptoHash::ByteHashToString( return res; } -std::vector<unsigned char> cmCryptoHash::ByteHashString( - const std::string& input) +std::vector<unsigned char> cmCryptoHash::ByteHashString(cm::string_view input) { this->Initialize(); - this->Append(reinterpret_cast<unsigned char const*>(input.c_str()), - static_cast<int>(input.size())); + this->Append(input); return this->Finalize(); } @@ -156,7 +153,7 @@ std::vector<unsigned char> cmCryptoHash::ByteHashFile(const std::string& file) return std::vector<unsigned char>(); } -std::string cmCryptoHash::HashString(const std::string& input) +std::string cmCryptoHash::HashString(cm::string_view input) { return ByteHashToString(this->ByteHashString(input)); } @@ -176,9 +173,9 @@ void cmCryptoHash::Append(void const* buf, size_t sz) rhash_update(this->CTX, buf, sz); } -void cmCryptoHash::Append(std::string const& str) +void cmCryptoHash::Append(cm::string_view input) { - this->Append(str.c_str(), str.size()); + rhash_update(this->CTX, input.data(), input.size()); } std::vector<unsigned char> cmCryptoHash::Finalize() diff --git a/Source/cmCryptoHash.h b/Source/cmCryptoHash.h index b712f09..681f5cc 100644 --- a/Source/cmCryptoHash.h +++ b/Source/cmCryptoHash.h @@ -5,7 +5,9 @@ #include "cmConfigure.h" // IWYU pragma: keep -#include <memory> // IWYU pragma: keep +#include "cm_string_view.hxx" + +#include <memory> #include <stddef.h> #include <string> #include <vector> @@ -42,7 +44,7 @@ public: /// SHA3_224, SHA3_256, SHA3_384, SHA3_512 /// @return A valid auto pointer if algo is supported or /// an invalid/NULL pointer otherwise - static std::unique_ptr<cmCryptoHash> New(const char* algo); + static std::unique_ptr<cmCryptoHash> New(cm::string_view algo); /// @brief Converts a hex character to its binary value (4 bits) /// @arg input Hex character [0-9a-fA-F]. @@ -55,7 +57,7 @@ public: /// @brief Calculates a binary hash from string input data /// @return Binary hash vector - std::vector<unsigned char> ByteHashString(const std::string& input); + std::vector<unsigned char> ByteHashString(cm::string_view input); /// @brief Calculates a binary hash from file content /// @see ByteHashString() @@ -65,7 +67,7 @@ public: /// @brief Calculates a hash string from string input data /// @return Sequence of hex characters pairs for each byte of the binary hash - std::string HashString(const std::string& input); + std::string HashString(cm::string_view input); /// @brief Calculates a hash string from file content /// @see HashString() @@ -75,7 +77,7 @@ public: void Initialize(); void Append(void const*, size_t); - void Append(std::string const& str); + void Append(cm::string_view input); std::vector<unsigned char> Finalize(); std::string FinalizeHex(); 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 fe228ff..82cc037 100644 --- a/Source/cmCustomCommandGenerator.cxx +++ b/Source/cmCustomCommandGenerator.cxx @@ -10,9 +10,10 @@ #include "cmLocalGenerator.h" #include "cmMakefile.h" #include "cmStateTypes.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" -#include <memory> // IWYU pragma: keep +#include <memory> #include <stddef.h> #include <utility> @@ -35,7 +36,7 @@ cmCustomCommandGenerator::cmCustomCommandGenerator(cmCustomCommand const& cc, this->GE->Parse(clarg); std::string parsed_arg = cge->Evaluate(this->LG, this->Config); if (this->CC.GetCommandExpandLists()) { - cmAppend(argv, cmSystemTools::ExpandedListArgument(parsed_arg)); + cmAppend(argv, cmExpandedList(parsed_arg)); } else { argv.push_back(std::move(parsed_arg)); } @@ -54,8 +55,8 @@ cmCustomCommandGenerator::cmCustomCommandGenerator(cmCustomCommand const& cc, std::vector<std::string> depends = this->CC.GetDepends(); for (std::string const& d : depends) { std::unique_ptr<cmCompiledGeneratorExpression> cge = this->GE->Parse(d); - std::vector<std::string> result = cmSystemTools::ExpandedListArgument( - cge->Evaluate(this->LG, this->Config)); + std::vector<std::string> result = + cmExpandedList(cge->Evaluate(this->LG, this->Config)); for (std::string& it : result) { if (cmSystemTools::FileIsFullPath(it)) { it = cmSystemTools::CollapseFullPath(it); @@ -108,8 +109,7 @@ void cmCustomCommandGenerator::FillEmulatorsWithArguments() continue; } - cmSystemTools::ExpandListArgument(emulator_property, - this->EmulatorsWithArguments[c]); + cmExpandList(emulator_property, this->EmulatorsWithArguments[c]); } } } @@ -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/cmDefinePropertyCommand.h b/Source/cmDefinePropertyCommand.h index a9c1856..36f97df 100644 --- a/Source/cmDefinePropertyCommand.h +++ b/Source/cmDefinePropertyCommand.h @@ -8,6 +8,8 @@ #include <string> #include <vector> +#include "cm_memory.hxx" + #include "cmCommand.h" class cmExecutionStatus; @@ -15,7 +17,10 @@ class cmExecutionStatus; class cmDefinePropertyCommand : public cmCommand { public: - cmCommand* Clone() override { return new cmDefinePropertyCommand; } + std::unique_ptr<cmCommand> Clone() override + { + return cm::make_unique<cmDefinePropertyCommand>(); + } /** * This is called when the command is first encountered in diff --git a/Source/cmDefinitions.cxx b/Source/cmDefinitions.cxx index 5fafaf9..e688890 100644 --- a/Source/cmDefinitions.cxx +++ b/Source/cmDefinitions.cxx @@ -2,8 +2,11 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmDefinitions.h" +#include "cm_string_view.hxx" + #include <assert.h> -#include <set> +#include <functional> +#include <unordered_set> #include <utility> cmDefinitions::Def cmDefinitions::NoDef; @@ -13,10 +16,12 @@ cmDefinitions::Def const& cmDefinitions::GetInternal(const std::string& key, StackIter end, bool raise) { assert(begin != end); - MapType::iterator i = begin->Map.find(key); - if (i != begin->Map.end()) { - i->second.Used = true; - return i->second; + { + auto it = begin->Map.find(cm::String::borrow(key)); + if (it != begin->Map.end()) { + it->second.Used = true; + return it->second; + } } StackIter it = begin; ++it; @@ -27,14 +32,14 @@ cmDefinitions::Def const& cmDefinitions::GetInternal(const std::string& key, if (!raise) { return def; } - return begin->Map.insert(MapType::value_type(key, def)).first->second; + return begin->Map.emplace(key, def).first->second; } 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 : nullptr; + return def.Value ? def.Value.str_if_stable() : nullptr; } void cmDefinitions::Raise(const std::string& key, StackIter begin, @@ -47,47 +52,27 @@ bool cmDefinitions::HasKey(const std::string& key, StackIter begin, StackIter end) { for (StackIter it = begin; it != end; ++it) { - MapType::const_iterator i = it->Map.find(key); - if (i != it->Map.end()) { + if (it->Map.find(cm::String::borrow(key)) != it->Map.end()) { return true; } } return false; } -void cmDefinitions::Set(const std::string& key, const char* value) -{ - Def def(value); - this->Map[key] = def; -} - -std::vector<std::string> cmDefinitions::UnusedKeys() const -{ - std::vector<std::string> keys; - keys.reserve(this->Map.size()); - // Consider local definitions. - for (auto const& mi : this->Map) { - if (!mi.second.Used) { - keys.push_back(mi.first); - } - } - return keys; -} - cmDefinitions cmDefinitions::MakeClosure(StackIter begin, StackIter end) { cmDefinitions closure; - std::set<std::string> undefined; + std::unordered_set<cm::string_view> undefined; for (StackIter it = begin; it != end; ++it) { // Consider local definitions. 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.insert(mi.first); + undefined.emplace(mi.first.view()); } } } @@ -98,18 +83,41 @@ cmDefinitions cmDefinitions::MakeClosure(StackIter begin, StackIter end) std::vector<std::string> cmDefinitions::ClosureKeys(StackIter begin, StackIter end) { - std::set<std::string> bound; std::vector<std::string> defined; + std::unordered_set<cm::string_view> bound; for (StackIter it = begin; it != end; ++it) { 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.insert(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()); } } } return defined; } + +void cmDefinitions::Set(const std::string& key, cm::string_view value) +{ + this->Map[key] = Def(value); +} + +void cmDefinitions::Unset(const std::string& key) +{ + this->Map[key] = Def(); +} + +std::vector<std::string> cmDefinitions::UnusedKeys() const +{ + std::vector<std::string> keys; + keys.reserve(this->Map.size()); + // Consider local definitions. + for (auto const& mi : this->Map) { + if (!mi.second.Used) { + keys.push_back(*mi.first.str_if_stable()); + } + } + return keys; +} diff --git a/Source/cmDefinitions.h b/Source/cmDefinitions.h index 6c252be..b4d6419 100644 --- a/Source/cmDefinitions.h +++ b/Source/cmDefinitions.h @@ -5,12 +5,16 @@ #include "cmConfigure.h" // IWYU pragma: keep +#include "cm_string_view.hxx" + +#include "cmLinkedTree.h" +#include "cmString.hxx" + +#include <functional> #include <string> #include <unordered_map> #include <vector> -#include "cmLinkedTree.h" - /** \class cmDefinitions * \brief Store a scope of variable definitions for CMake language. * @@ -23,6 +27,8 @@ class cmDefinitions typedef cmLinkedTree<cmDefinitions>::iterator StackIter; public: + // -- Static member functions + static const std::string* Get(const std::string& key, StackIter begin, StackIter end); @@ -30,41 +36,37 @@ public: static bool HasKey(const std::string& key, StackIter begin, StackIter end); - /** Set (or unset if null) a value associated with a key. */ - void Set(const std::string& key, const char* value); - - std::vector<std::string> UnusedKeys() const; - static std::vector<std::string> ClosureKeys(StackIter begin, StackIter end); static cmDefinitions MakeClosure(StackIter begin, StackIter end); + // -- Member functions + + /** Set a value associated with a key. */ + void Set(const std::string& key, cm::string_view value); + + /** Unset a definition. */ + void Unset(const std::string& key); + + /** List of unused keys. */ + std::vector<std::string> UnusedKeys() const; + private: - // String with existence boolean. - struct Def : public std::string + /** String with existence boolean. */ + struct Def { - private: - typedef std::string std_string; - public: Def() = default; - Def(const char* v) - : std_string(v ? v : "") - , Exists(v ? true : false) - { - } - Def(const std_string& v) - : std_string(v) - , Exists(true) + Def(cm::string_view value) + : Value(value) { } - bool Exists = false; + cm::String Value; bool Used = false; }; static Def NoDef; - typedef std::unordered_map<std::string, Def> MapType; - MapType 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 ed76dbf..06a442b 100644 --- a/Source/cmDepends.cxx +++ b/Source/cmDepends.cxx @@ -7,6 +7,7 @@ #include "cmGeneratedFileStream.h" #include "cmLocalGenerator.h" #include "cmMakefile.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmsys/FStream.hxx" @@ -30,7 +31,7 @@ bool cmDepends::Write(std::ostream& makeDepends, std::ostream& internalDepends) { std::string const srcLang = "CMAKE_DEPENDS_CHECK_" + this->Language; cmMakefile* mf = this->LocalGenerator->GetMakefile(); - cmSystemTools::ExpandListArgument(mf->GetSafeDefinition(srcLang), pairs); + cmExpandList(mf->GetSafeDefinition(srcLang), pairs); } for (std::vector<std::string>::iterator si = pairs.begin(); si != pairs.end();) { @@ -235,21 +236,18 @@ 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) { - cmSystemTools::ExpandListArgument(includePath, this->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) { - cmSystemTools::ExpandListArgument(includePath, this->IncludePath); + cmExpandList(includePath, this->IncludePath); } } } diff --git a/Source/cmDependsC.cxx b/Source/cmDependsC.cxx index dc49c18..0f9f166 100644 --- a/Source/cmDependsC.cxx +++ b/Source/cmDependsC.cxx @@ -9,6 +9,7 @@ #include "cmFileTime.h" #include "cmLocalGenerator.h" #include "cmMakefile.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #define INCLUDE_REGEX_LINE \ @@ -35,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; } @@ -53,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(); } @@ -391,7 +387,7 @@ void cmDependsC::SetupTransforms() std::vector<std::string> transformRules; cmMakefile* mf = this->LocalGenerator->GetMakefile(); if (const char* xform = mf->GetDefinition("CMAKE_INCLUDE_TRANSFORMS")) { - cmSystemTools::ExpandListArgument(xform, transformRules, true); + cmExpandList(xform, transformRules, true); } for (std::string const& tr : transformRules) { this->ParseTransform(tr); diff --git a/Source/cmDependsFortran.cxx b/Source/cmDependsFortran.cxx index 178e18b..6c77db9 100644 --- a/Source/cmDependsFortran.cxx +++ b/Source/cmDependsFortran.cxx @@ -9,7 +9,6 @@ #include <stdlib.h> #include <utility> -#include "cmAlgorithms.h" #include "cmFortranParser.h" /* Interface to parser object. */ #include "cmGeneratedFileStream.h" #include "cmLocalGenerator.h" @@ -17,6 +16,7 @@ #include "cmOutputConverter.h" #include "cmStateDirectory.h" #include "cmStateSnapshot.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" // TODO: Test compiler for the case of the mod file. Some always @@ -82,7 +82,7 @@ cmDependsFortran::cmDependsFortran(cmLocalGenerator* lg) cmMakefile* mf = this->LocalGenerator->GetMakefile(); if (const char* c_defines = mf->GetDefinition("CMAKE_TARGET_DEFINITIONS_Fortran")) { - cmSystemTools::ExpandListArgument(c_defines, definitions); + cmExpandList(c_defines, definitions); } // translate i.e. FOO=BAR to FOO and add it to the list of defined @@ -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) @@ -254,7 +248,7 @@ void cmDependsFortran::LocateModules() std::vector<std::string> infoFiles; if (const char* infoFilesValue = mf->GetDefinition("CMAKE_TARGET_LINKED_INFO_FILES")) { - cmSystemTools::ExpandListArgument(infoFilesValue, infoFiles); + cmExpandList(infoFilesValue, infoFiles); } for (std::string const& i : infoFiles) { std::string targetDir = cmSystemTools::GetFilenamePath(i); @@ -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 index 418d98c..aa1f90b 100644 --- a/Source/cmDisallowedCommand.cxx +++ b/Source/cmDisallowedCommand.cxx @@ -24,8 +24,6 @@ bool cmDisallowedCommand::InitialPass(std::vector<std::string> const& args, return true; } - this->Command->SetMakefile(this->GetMakefile()); - bool const ret = this->Command->InitialPass(args, status); - this->SetError(this->Command->GetError()); - return ret; + this->Command->SetExecutionStatus(this->GetExecutionStatus()); + return this->Command->InitialPass(args, status); } diff --git a/Source/cmDisallowedCommand.h b/Source/cmDisallowedCommand.h index d85c00f..e07f255 100644 --- a/Source/cmDisallowedCommand.h +++ b/Source/cmDisallowedCommand.h @@ -6,8 +6,11 @@ #include "cmConfigure.h" // IWYU pragma: keep #include <string> +#include <utility> #include <vector> +#include "cm_memory.hxx" + #include "cmCommand.h" #include "cmPolicies.h" @@ -16,31 +19,27 @@ class cmExecutionStatus; class cmDisallowedCommand : public cmCommand { public: - cmDisallowedCommand(cmCommand* command, cmPolicies::PolicyID policy, - const char* message) - : Command(command) + cmDisallowedCommand(std::unique_ptr<cmCommand> command, + cmPolicies::PolicyID policy, const char* message) + : Command(std::move(command)) , Policy(policy) , Message(message) { } - ~cmDisallowedCommand() override { delete this->Command; } + ~cmDisallowedCommand() override = default; - cmCommand* Clone() override + std::unique_ptr<cmCommand> Clone() override { - return new cmDisallowedCommand(this->Command->Clone(), this->Policy, - this->Message); + return cm::make_unique<cmDisallowedCommand>(this->Command->Clone(), + this->Policy, this->Message); } bool InitialPass(std::vector<std::string> const& args, cmExecutionStatus& status) override; - void FinalPass() override { this->Command->FinalPass(); } - - bool HasFinalPass() const override { return this->Command->HasFinalPass(); } - private: - cmCommand* Command; + std::unique_ptr<cmCommand> Command; cmPolicies::PolicyID Policy; const char* Message; }; diff --git a/Source/cmELF.cxx b/Source/cmELF.cxx index 2226463..096016d 100644 --- a/Source/cmELF.cxx +++ b/Source/cmELF.cxx @@ -4,9 +4,10 @@ #include "cmAlgorithms.h" #include "cm_kwiml.h" +#include "cm_memory.hxx" #include "cmsys/FStream.hxx" #include <map> -#include <memory> // IWYU pragma: keep +#include <memory> #include <sstream> #include <stddef.h> #include <utility> @@ -109,10 +110,10 @@ public: }; // Construct and take ownership of the file stream object. - cmELFInternal(cmELF* external, std::unique_ptr<cmsys::ifstream>& fin, + cmELFInternal(cmELF* external, std::unique_ptr<std::istream> fin, ByteOrderType order) : External(external) - , Stream(*fin.release()) + , Stream(std::move(fin)) , ByteOrder(order) , ELFType(cmELF::FileTypeInvalid) { @@ -132,7 +133,7 @@ public: } // Destruct and delete the file stream object. - virtual ~cmELFInternal() { delete &this->Stream; } + virtual ~cmELFInternal() = default; // Forward to the per-class implementation. virtual unsigned int GetNumberOfSections() const = 0; @@ -171,7 +172,7 @@ protected: cmELF* External; // The stream from which to read. - std::istream& Stream; + std::unique_ptr<std::istream> Stream; // The byte order of the ELF file. ByteOrderType ByteOrder; @@ -233,7 +234,7 @@ public: typedef typename Types::tagtype tagtype; // Construct with a stream and byte swap indicator. - cmELFInternalImpl(cmELF* external, std::unique_ptr<cmsys::ifstream>& fin, + cmELFInternalImpl(cmELF* external, std::unique_ptr<std::istream> fin, ByteOrderType order); // Return the number of sections as specified by the ELF header. @@ -352,7 +353,7 @@ private: bool Read(ELF_Ehdr& x) { // Read the header from the file. - if (!this->Stream.read(reinterpret_cast<char*>(&x), sizeof(x))) { + if (!this->Stream->read(reinterpret_cast<char*>(&x), sizeof(x))) { return false; } @@ -382,26 +383,26 @@ private: } bool Read(ELF_Shdr& x) { - if (this->Stream.read(reinterpret_cast<char*>(&x), sizeof(x)) && + if (this->Stream->read(reinterpret_cast<char*>(&x), sizeof(x)) && this->NeedSwap) { ByteSwap(x); } - return !this->Stream.fail(); + return !this->Stream->fail(); } bool Read(ELF_Dyn& x) { - if (this->Stream.read(reinterpret_cast<char*>(&x), sizeof(x)) && + if (this->Stream->read(reinterpret_cast<char*>(&x), sizeof(x)) && this->NeedSwap) { ByteSwap(x); } - return !this->Stream.fail(); + return !this->Stream->fail(); } bool LoadSectionHeader(ELF_Half i) { // Read the section header from the file. - this->Stream.seekg(this->ELFHeader.e_shoff + - this->ELFHeader.e_shentsize * i); + this->Stream->seekg(this->ELFHeader.e_shoff + + this->ELFHeader.e_shentsize * i); if (!this->Read(this->SectionHeaders[i])) { return false; } @@ -426,9 +427,10 @@ private: }; template <class Types> -cmELFInternalImpl<Types>::cmELFInternalImpl( - cmELF* external, std::unique_ptr<cmsys::ifstream>& fin, ByteOrderType order) - : cmELFInternal(external, fin, order) +cmELFInternalImpl<Types>::cmELFInternalImpl(cmELF* external, + std::unique_ptr<std::istream> fin, + ByteOrderType order) + : cmELFInternal(external, std::move(fin), order) { // Read the main header. if (!this->Read(this->ELFHeader)) { @@ -510,7 +512,7 @@ bool cmELFInternalImpl<Types>::LoadDynamicSection() // Read each entry. for (int j = 0; j < n; ++j) { // Seek to the beginning of the section entry. - this->Stream.seekg(sec.sh_offset + sec.sh_entsize * j); + this->Stream->seekg(sec.sh_offset + sec.sh_entsize * j); ELF_Dyn& dyn = this->DynamicSectionEntries[j]; // Try reading the entry. @@ -630,7 +632,7 @@ cmELF::StringEntry const* cmELFInternalImpl<Types>::GetDynamicSectionString( unsigned long first = static_cast<unsigned long>(dyn.d_un.d_val); unsigned long last = first; unsigned long end = static_cast<unsigned long>(strtab.sh_size); - this->Stream.seekg(strtab.sh_offset + first); + this->Stream->seekg(strtab.sh_offset + first); // Read the string. It may be followed by more than one NULL // terminator. Count the total size of the region allocated to @@ -639,7 +641,7 @@ cmELF::StringEntry const* cmELFInternalImpl<Types>::GetDynamicSectionString( // assumption. bool terminated = false; char c; - while (last != end && this->Stream.get(c) && !(terminated && c)) { + while (last != end && this->Stream->get(c) && !(terminated && c)) { ++last; if (c) { se.Value += c; @@ -649,7 +651,7 @@ cmELF::StringEntry const* cmELFInternalImpl<Types>::GetDynamicSectionString( } // Make sure the whole value was read. - if (!this->Stream) { + if (!(*this->Stream)) { this->SetErrorMessage("Dynamic section specifies unreadable RPATH."); se.Value = ""; return nullptr; @@ -679,10 +681,9 @@ const long cmELF::TagMipsRldMapRel = 0; #endif cmELF::cmELF(const char* fname) - : Internal(nullptr) { // Try to open the file. - std::unique_ptr<cmsys::ifstream> fin(new cmsys::ifstream(fname)); + auto fin = cm::make_unique<cmsys::ifstream>(fname); // Quit now if the file could not be opened. if (!fin || !*fin) { @@ -725,12 +726,14 @@ cmELF::cmELF(const char* fname) // parser implementation. if (ident[EI_CLASS] == ELFCLASS32) { // 32-bit ELF - this->Internal = new cmELFInternalImpl<cmELFTypes32>(this, fin, order); + this->Internal = cm::make_unique<cmELFInternalImpl<cmELFTypes32>>( + this, std::move(fin), order); } #ifndef _SCO_DS else if (ident[EI_CLASS] == ELFCLASS64) { // 64-bit ELF - this->Internal = new cmELFInternalImpl<cmELFTypes64>(this, fin, order); + this->Internal = cm::make_unique<cmELFInternalImpl<cmELFTypes64>>( + this, std::move(fin), order); } #endif else { @@ -739,10 +742,7 @@ cmELF::cmELF(const char* fname) } } -cmELF::~cmELF() -{ - delete this->Internal; -} +cmELF::~cmELF() = default; bool cmELF::Valid() const { diff --git a/Source/cmELF.h b/Source/cmELF.h index 987f0c3..afef654 100644 --- a/Source/cmELF.h +++ b/Source/cmELF.h @@ -6,6 +6,7 @@ #include "cmConfigure.h" // IWYU pragma: keep #include <iosfwd> +#include <memory> #include <string> #include <utility> #include <vector> @@ -108,7 +109,7 @@ public: private: friend class cmELFInternal; bool Valid() const; - cmELFInternal* Internal; + std::unique_ptr<cmELFInternal> Internal; std::string ErrorMessage; }; diff --git a/Source/cmEnableLanguageCommand.h b/Source/cmEnableLanguageCommand.h index 97645a9..dc43e34 100644 --- a/Source/cmEnableLanguageCommand.h +++ b/Source/cmEnableLanguageCommand.h @@ -8,6 +8,8 @@ #include <string> #include <vector> +#include "cm_memory.hxx" + #include "cmCommand.h" class cmExecutionStatus; @@ -26,7 +28,10 @@ public: /** * This is a virtual constructor for the command. */ - cmCommand* Clone() override { return new cmEnableLanguageCommand; } + std::unique_ptr<cmCommand> Clone() override + { + return cm::make_unique<cmEnableLanguageCommand>(); + } /** * This is called when the command is first encountered in diff --git a/Source/cmEnableTestingCommand.cxx b/Source/cmEnableTestingCommand.cxx index 6a64450..89212c8 100644 --- a/Source/cmEnableTestingCommand.cxx +++ b/Source/cmEnableTestingCommand.cxx @@ -2,15 +2,12 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmEnableTestingCommand.h" +#include "cmExecutionStatus.h" #include "cmMakefile.h" -class cmExecutionStatus; - -// we do this in the final pass so that we now the subdirs have all -// been defined -bool cmEnableTestingCommand::InitialPass(std::vector<std::string> const&, - cmExecutionStatus&) +bool cmEnableTestingCommand(std::vector<std::string> const&, + cmExecutionStatus& status) { - this->Makefile->AddDefinition("CMAKE_TESTING_ENABLED", "1"); + status.GetMakefile().AddDefinition("CMAKE_TESTING_ENABLED", "1"); return true; } diff --git a/Source/cmEnableTestingCommand.h b/Source/cmEnableTestingCommand.h index 88a17b9..e4593f2 100644 --- a/Source/cmEnableTestingCommand.h +++ b/Source/cmEnableTestingCommand.h @@ -8,11 +8,9 @@ #include <string> #include <vector> -#include "cmCommand.h" - class cmExecutionStatus; -/** \class cmEnableTestingCommand +/** * \brief Enable testing for this directory and below. * * Produce the output testfile. This produces a file in the build directory @@ -25,20 +23,7 @@ class cmExecutionStatus; * Note that CTest expects to find this file in the build directory root; * therefore, this command should be in the source directory root too. */ -class cmEnableTestingCommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - cmCommand* Clone() override { return new cmEnableTestingCommand; } - - /** - * This is called when the command is first encountered in - * the CMakeLists.txt file. - */ - bool InitialPass(std::vector<std::string> const&, - cmExecutionStatus&) override; -}; +bool cmEnableTestingCommand(std::vector<std::string> const&, + cmExecutionStatus&); #endif diff --git a/Source/cmExecProgramCommand.cxx b/Source/cmExecProgramCommand.cxx index 4b559e7..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.c_str()); + 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 ae0fa9b..7c751e1 100644 --- a/Source/cmExecProgramCommand.h +++ b/Source/cmExecProgramCommand.h @@ -8,38 +8,16 @@ #include <string> #include <vector> -#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. - */ - cmCommand* Clone() override { return new 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 494afbb..acf2a83 100644 --- a/Source/cmExecuteProcessCommand.cxx +++ b/Source/cmExecuteProcessCommand.cxx @@ -4,21 +4,25 @@ #include "cm_static_string_view.hxx" #include "cmsys/Process.h" + #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'); } @@ -27,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; } @@ -84,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; } } @@ -117,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; } } @@ -177,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; @@ -201,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; } } @@ -275,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. @@ -289,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; } } @@ -329,20 +336,20 @@ bool cmExecuteProcessCommand::InitialPass(std::vector<std::string> const& args, break; } } - this->Makefile->AddDefinition(arguments.ResultsVariable, - cmJoin(res, ";").c_str()); + 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; } } @@ -350,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) { @@ -395,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 b415deb..9c4b600 100644 --- a/Source/cmExecuteProcessCommand.h +++ b/Source/cmExecuteProcessCommand.h @@ -8,30 +8,15 @@ #include <string> #include <vector> -#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. - */ - cmCommand* Clone() override { return new 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/cmExecutionStatus.h b/Source/cmExecutionStatus.h index 56199dd..654922c 100644 --- a/Source/cmExecutionStatus.h +++ b/Source/cmExecutionStatus.h @@ -3,6 +3,11 @@ #ifndef cmExecutionStatus_h #define cmExecutionStatus_h +#include <cmConfigure.h> // IWYU pragma: keep +#include <string> + +class cmMakefile; + /** \class cmExecutionStatus * \brief Superclass for all command status classes * @@ -11,14 +16,17 @@ class cmExecutionStatus { public: - void Clear() + cmExecutionStatus(cmMakefile& makefile) + : Makefile(makefile) + , Error("unknown error.") { - this->ReturnInvoked = false; - this->BreakInvoked = false; - this->ContinueInvoked = false; - this->NestedError = false; } + cmMakefile& GetMakefile() { return this->Makefile; } + + void SetError(std::string const& e) { this->Error = e; } + std::string const& GetError() const { return this->Error; } + void SetReturnInvoked() { this->ReturnInvoked = true; } bool GetReturnInvoked() const { return this->ReturnInvoked; } @@ -32,6 +40,8 @@ public: bool GetNestedError() const { return this->NestedError; } private: + cmMakefile& Makefile; + std::string Error; bool ReturnInvoked = false; bool BreakInvoked = false; bool ContinueInvoked = false; diff --git a/Source/cmExportBuildAndroidMKGenerator.cxx b/Source/cmExportBuildAndroidMKGenerator.cxx index ced27c9..561e830 100644 --- a/Source/cmExportBuildAndroidMKGenerator.cxx +++ b/Source/cmExportBuildAndroidMKGenerator.cxx @@ -2,8 +2,6 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmExportBuildAndroidMKGenerator.h" -#include <algorithm> -#include <memory> // IWYU pragma: keep #include <sstream> #include <utility> @@ -14,6 +12,7 @@ #include "cmMessageType.h" #include "cmPolicies.h" #include "cmStateTypes.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmTarget.h" @@ -42,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"; @@ -145,8 +143,7 @@ void cmExportBuildAndroidMKGenerator::GenerateInterfaceProperties( } } else if (property.first == "INTERFACE_INCLUDE_DIRECTORIES") { std::string includes = property.second; - std::vector<std::string> includeList; - cmSystemTools::ExpandListArgument(includes, includeList); + std::vector<std::string> includeList = cmExpandedList(includes); os << "LOCAL_EXPORT_C_INCLUDES := "; std::string end; for (std::string const& i : includeList) { @@ -156,8 +153,8 @@ void cmExportBuildAndroidMKGenerator::GenerateInterfaceProperties( os << "\n"; } else if (property.first == "INTERFACE_LINK_OPTIONS") { os << "LOCAL_EXPORT_LDFLAGS := "; - std::vector<std::string> linkFlagsList; - cmSystemTools::ExpandListArgument(property.second, linkFlagsList); + std::vector<std::string> linkFlagsList = + cmExpandedList(property.second); os << cmJoin(linkFlagsList, " ") << "\n"; } else { os << "# " << property.first << " " << (property.second) << "\n"; @@ -168,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 012355b..8a1a305 100644 --- a/Source/cmExportBuildFileGenerator.cxx +++ b/Source/cmExportBuildFileGenerator.cxx @@ -2,7 +2,6 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmExportBuildFileGenerator.h" -#include "cmAlgorithms.h" #include "cmExportSet.h" #include "cmGeneratorExpression.h" #include "cmGeneratorTarget.h" @@ -12,12 +11,11 @@ #include "cmMessageType.h" #include "cmPolicies.h" #include "cmStateTypes.h" -#include "cmSystemTools.h" +#include "cmStringAlgorithms.h" #include "cmTarget.h" #include "cmTargetExport.h" #include "cmake.h" -#include <algorithm> #include <map> #include <set> #include <sstream> @@ -45,6 +43,7 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os) std::string expectedTargets; std::string sep; std::vector<std::string> targets; + bool generatedInterfaceRequired = false; this->GetTargets(targets); for (std::string const& tei : targets) { cmGeneratorTarget* te = this->LG->FindGeneratorTargetToUse(tei); @@ -60,11 +59,13 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os) this->LG->GetMakefile()->GetBacktrace()); return false; } - if (this->GetExportTargetType(te) == cmStateEnums::INTERFACE_LIBRARY) { - this->GenerateRequiredCMakeVersion(os, "3.0.0"); - } + generatedInterfaceRequired |= + this->GetExportTargetType(te) == cmStateEnums::INTERFACE_LIBRARY; } + if (generatedInterfaceRequired) { + this->GenerateRequiredCMakeVersion(os, "3.0.0"); + } this->GenerateExpectedTargetsCode(os, expectedTargets); } @@ -201,8 +202,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 @@ -220,8 +220,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 = @@ -234,14 +233,14 @@ void cmExportBuildFileGenerator::SetImportLocationProperty( } // Add the import library for windows DLLs. - if (target->HasImportLibrary(config) && - mf->GetDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX")) { - std::string prop = "IMPORTED_IMPLIB"; - prop += suffix; + if (target->HasImportLibrary(config)) { + std::string prop = cmStrCat("IMPORTED_IMPLIB", suffix); std::string value = target->GetFullPath(config, cmStateEnums::ImportLibraryArtifact); - target->GetImplibGNUtoMS(config, value, value, - "${CMAKE_IMPORT_LIBRARY_SUFFIX}"); + if (mf->GetDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX")) { + target->GetImplibGNUtoMS(config, value, value, + "${CMAKE_IMPORT_LIBRARY_SUFFIX}"); + } properties[prop] = value; } } @@ -256,11 +255,11 @@ void cmExportBuildFileGenerator::HandleMissingTarget( const std::string name = dependee->GetName(); cmGlobalGenerator* gg = dependee->GetLocalGenerator()->GetGlobalGenerator(); - std::vector<std::string> namespaces = this->FindNamespaces(gg, name); + auto exportInfo = this->FindBuildExportInfo(gg, name); + std::vector<std::string> const& exportFiles = exportInfo.first; - int targetOccurrences = static_cast<int>(namespaces.size()); - if (targetOccurrences == 1) { - std::string missingTarget = namespaces[0]; + if (exportFiles.size() == 1) { + std::string missingTarget = exportInfo.second; missingTarget += dependee->GetExportName(); link_libs += missingTarget; @@ -269,7 +268,7 @@ void cmExportBuildFileGenerator::HandleMissingTarget( } // We are not appending, so all exported targets should be // known here. This is probably user-error. - this->ComplainAboutMissingTarget(depender, dependee, targetOccurrences); + this->ComplainAboutMissingTarget(depender, dependee, exportFiles); } // Assume the target will be exported by another command. // Append it with the export namespace. @@ -289,10 +288,12 @@ void cmExportBuildFileGenerator::GetTargets( targets = this->Targets; } -std::vector<std::string> cmExportBuildFileGenerator::FindNamespaces( - cmGlobalGenerator* gg, const std::string& name) +std::pair<std::vector<std::string>, std::string> +cmExportBuildFileGenerator::FindBuildExportInfo(cmGlobalGenerator* gg, + const std::string& name) { - std::vector<std::string> namespaces; + std::vector<std::string> exportFiles; + std::string ns; std::map<std::string, cmExportBuildFileGenerator*>& exportSets = gg->GetBuildExportSets(); @@ -301,32 +302,32 @@ std::vector<std::string> cmExportBuildFileGenerator::FindNamespaces( const cmExportBuildFileGenerator* exportSet = exp.second; std::vector<std::string> targets; exportSet->GetTargets(targets); - if (std::find(targets.begin(), targets.end(), name) != targets.end()) { - namespaces.push_back(exportSet->GetNamespace()); + if (cmContains(targets, name)) { + exportFiles.push_back(exp.first); + ns = exportSet->GetNamespace(); } } - return namespaces; + return std::make_pair(exportFiles, ns); } void cmExportBuildFileGenerator::ComplainAboutMissingTarget( - cmGeneratorTarget* depender, cmGeneratorTarget* dependee, int occurrences) + cmGeneratorTarget* depender, cmGeneratorTarget* dependee, + std::vector<std::string> const& exportFiles) { - if (cmSystemTools::GetErrorOccuredFlag()) { - return; - } - std::ostringstream e; e << "export called with target \"" << depender->GetName() << "\" which requires target \"" << dependee->GetName() << "\" "; - if (occurrences == 0) { - e << "that is not in the export set.\n"; + 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.\n"; + 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."; } - e << "If the required target is not easy to reference in this call, " - << "consider using the APPEND option with multiple separate calls."; this->LG->GetGlobalGenerator()->GetCMakeInstance()->IssueMessage( MessageType::FATAL_ERROR, e.str(), diff --git a/Source/cmExportBuildFileGenerator.h b/Source/cmExportBuildFileGenerator.h index 0a1e755..e5b6597 100644 --- a/Source/cmExportBuildFileGenerator.h +++ b/Source/cmExportBuildFileGenerator.h @@ -11,6 +11,7 @@ #include <iosfwd> #include <string> +#include <utility> #include <vector> class cmExportSet; @@ -64,7 +65,7 @@ protected: void ComplainAboutMissingTarget(cmGeneratorTarget* depender, cmGeneratorTarget* dependee, - int occurrences); + std::vector<std::string> const& namespaces); /** Fill in properties indicating built file locations. */ void SetImportLocationProperty(const std::string& config, @@ -75,8 +76,8 @@ protected: std::string InstallNameDir(cmGeneratorTarget* target, const std::string& config) override; - std::vector<std::string> FindNamespaces(cmGlobalGenerator* gg, - const std::string& name); + std::pair<std::vector<std::string>, std::string> FindBuildExportInfo( + cmGlobalGenerator* gg, const std::string& name); std::vector<std::string> Targets; cmExportSet* ExportSet; 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/cmExportCommand.h b/Source/cmExportCommand.h index 99f9932..50463af 100644 --- a/Source/cmExportCommand.h +++ b/Source/cmExportCommand.h @@ -8,6 +8,8 @@ #include <string> #include <vector> +#include "cm_memory.hxx" + #include "cmCommand.h" class cmExecutionStatus; @@ -18,7 +20,10 @@ public: /** * This is a virtual constructor for the command. */ - cmCommand* Clone() override { return new cmExportCommand; } + std::unique_ptr<cmCommand> Clone() override + { + return cm::make_unique<cmExportCommand>(); + } /** * This is called when the command is first encountered in diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx index a12e0c4..70f98bf 100644 --- a/Source/cmExportFileGenerator.cxx +++ b/Source/cmExportFileGenerator.cxx @@ -2,7 +2,6 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmExportFileGenerator.h" -#include "cmAlgorithms.h" #include "cmComputeLinkInformation.h" #include "cmGeneratedFileStream.h" #include "cmGeneratorTarget.h" @@ -12,20 +11,21 @@ #include "cmMessageType.h" #include "cmOutputConverter.h" #include "cmPolicies.h" -#include "cmProperty.h" #include "cmPropertyMap.h" #include "cmStateTypes.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmTarget.h" #include "cmTargetExport.h" #include "cmsys/FStream.hxx" #include <assert.h> -#include <memory> // IWYU pragma: keep #include <sstream> #include <string.h> #include <utility> +#include "cm_memory.hxx" + static std::string cmExportFileGeneratorEscape(std::string const& str) { // Escape a property value for writing into a .cmake file. @@ -499,8 +499,7 @@ void getPropertyContents(cmGeneratorTarget const* tgt, const std::string& prop, if (!p) { return; } - std::vector<std::string> content; - cmSystemTools::ExpandListArgument(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" @@ -1205,15 +1199,12 @@ bool cmExportFileGenerator::PopulateExportProperties( std::string& errorMessage) { auto& targetProperties = gte->Target->GetProperties(); - const auto& exportProperties = targetProperties.find("EXPORT_PROPERTIES"); - if (exportProperties != targetProperties.end()) { - std::vector<std::string> propsToExport; - cmSystemTools::ExpandListArgument(exportProperties->second.GetValue(), - propsToExport); - for (auto& prop : propsToExport) { + if (const char* exportProperties = + targetProperties.GetPropertyValue("EXPORT_PROPERTIES")) { + for (auto& prop : cmExpandedList(exportProperties)) { /* Black list reserved properties */ - if (cmSystemTools::StringStartsWith(prop, "IMPORTED_") || - cmSystemTools::StringStartsWith(prop, "INTERFACE_")) { + if (cmHasLiteralPrefix(prop, "IMPORTED_") || + cmHasLiteralPrefix(prop, "INTERFACE_")) { std::ostringstream e; e << "Target \"" << gte->Target->GetName() << "\" contains property \"" << prop << "\" in EXPORT_PROPERTIES but IMPORTED_* and INTERFACE_* " 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 f8bc0ab..e7f301e 100644 --- a/Source/cmExportInstallFileGenerator.cxx +++ b/Source/cmExportInstallFileGenerator.cxx @@ -2,7 +2,6 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmExportInstallFileGenerator.h" -#include "cmAlgorithms.h" #include "cmExportSet.h" #include "cmExportSetMap.h" #include "cmGeneratedFileStream.h" @@ -15,6 +14,7 @@ #include "cmMakefile.h" #include "cmPolicies.h" #include "cmStateTypes.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmTarget.h" #include "cmTargetExport.h" @@ -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,15 +398,14 @@ 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 std::vector<std::string> objects; itgen->GetInstallObjectNames(config, objects); for (std::string& obj : objects) { - obj = value + obj; + obj = cmStrCat(value, obj); } // Store the property. @@ -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 b60a053..81237db 100644 --- a/Source/cmExportLibraryDependenciesCommand.cxx +++ b/Source/cmExportLibraryDependenciesCommand.cxx @@ -4,14 +4,15 @@ #include "cmsys/FStream.hxx" #include <map> -#include <memory> // IWYU pragma: keep #include <utility> -#include "cmAlgorithms.h" +#include "cm_memory.hxx" + #include "cmGeneratedFileStream.h" #include "cmGlobalGenerator.h" #include "cmMakefile.h" #include "cmStateTypes.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmTarget.h" #include "cmTargetLinkLibraryType.h" @@ -19,57 +20,31 @@ class cmExecutionStatus; -bool cmExportLibraryDependenciesCommand::InitialPass( - std::vector<std::string> const& args, cmExecutionStatus&) -{ - if (args.empty()) { - this->SetError("called with incorrect number of arguments"); - return false; - } - - // store the arguments for the final pass - this->Filename = args[0]; - this->Append = false; - if (args.size() > 1) { - if (args[1] == "APPEND") { - this->Append = true; - } - } - return true; -} - -void cmExportLibraryDependenciesCommand::FinalPass() -{ - // export_library_dependencies() shouldn't modify anything - // ensure this by calling a const method - this->ConstFinalPass(); -} - -void cmExportLibraryDependenciesCommand::ConstFinalPass() const +static void FinalAction(cmMakefile& makefile, std::string const& filename, + bool append) { // Use copy-if-different if not appending. std::unique_ptr<cmsys::ofstream> foutPtr; - if (this->Append) { + if (append) { const auto openmodeApp = std::ios::app; - foutPtr = - cm::make_unique<cmsys::ofstream>(this->Filename.c_str(), openmodeApp); + foutPtr = cm::make_unique<cmsys::ofstream>(filename.c_str(), openmodeApp); } else { std::unique_ptr<cmGeneratedFileStream> ap( - new cmGeneratedFileStream(this->Filename, true)); + new cmGeneratedFileStream(filename, true)); ap->SetCopyIfDifferent(true); foutPtr = std::move(ap); } std::ostream& fout = *foutPtr; if (!fout) { - cmSystemTools::Error("Error Writing " + this->Filename); + cmSystemTools::Error("Error Writing " + filename); cmSystemTools::ReportLastSystemError(""); return; } // Collect dependency information about all library targets built in // the project. - cmake* cm = this->Makefile->GetCMakeInstance(); + cmake* cm = makefile.GetCMakeInstance(); cmGlobalGenerator* global = cm->GetGlobalGenerator(); const std::vector<cmMakefile*>& locals = global->GetMakefiles(); std::map<std::string, std::string> libDepsOld; @@ -87,8 +62,7 @@ void cmExportLibraryDependenciesCommand::ConstFinalPass() const } // 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. @@ -97,8 +71,7 @@ void cmExportLibraryDependenciesCommand::ConstFinalPass() const 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: @@ -166,3 +139,20 @@ void cmExportLibraryDependenciesCommand::ConstFinalPass() const } fout << "endif()\n"; } + +bool cmExportLibraryDependenciesCommand::InitialPass( + std::vector<std::string> const& args, cmExecutionStatus&) +{ + if (args.empty()) { + this->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); + }); + + return true; +} diff --git a/Source/cmExportLibraryDependenciesCommand.h b/Source/cmExportLibraryDependenciesCommand.h index 8414866..4817162 100644 --- a/Source/cmExportLibraryDependenciesCommand.h +++ b/Source/cmExportLibraryDependenciesCommand.h @@ -8,6 +8,8 @@ #include <string> #include <vector> +#include "cm_memory.hxx" + #include "cmCommand.h" class cmExecutionStatus; @@ -15,20 +17,12 @@ class cmExecutionStatus; class cmExportLibraryDependenciesCommand : public cmCommand { public: - cmCommand* Clone() override + std::unique_ptr<cmCommand> Clone() override { - return new cmExportLibraryDependenciesCommand; + return cm::make_unique<cmExportLibraryDependenciesCommand>(); } bool InitialPass(std::vector<std::string> const& args, cmExecutionStatus& status) override; - - void FinalPass() override; - bool HasFinalPass() const override { return true; } - -private: - std::string Filename; - bool Append = false; - void ConstFinalPass() const; }; #endif diff --git a/Source/cmExportTryCompileFileGenerator.cxx b/Source/cmExportTryCompileFileGenerator.cxx index c169032..5631d60 100644 --- a/Source/cmExportTryCompileFileGenerator.cxx +++ b/Source/cmExportTryCompileFileGenerator.cxx @@ -9,11 +9,11 @@ #include "cmLocalGenerator.h" #include "cmMakefile.h" #include "cmStateTypes.h" -#include "cmSystemTools.h" +#include "cmStringAlgorithms.h" #include "cmTarget.h" #include <map> -#include <memory> // IWYU pragma: keep +#include <memory> #include <utility> cmExportTryCompileFileGenerator::cmExportTryCompileFileGenerator( @@ -103,8 +103,7 @@ void cmExportTryCompileFileGenerator::PopulateProperties( std::string evalResult = this->FindTargets(p, target, std::string(), emitted); - std::vector<std::string> depends; - cmSystemTools::ExpandListArgument(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 f47744b..d8a1a49 100644 --- a/Source/cmExtraCodeBlocksGenerator.cxx +++ b/Source/cmExtraCodeBlocksGenerator.cxx @@ -16,6 +16,7 @@ #include "cmRange.h" #include "cmSourceFile.h" #include "cmStateTypes.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmXMLWriter.h" #include "cmake.h" @@ -73,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); } @@ -178,18 +178,18 @@ void Tree::BuildUnitImpl(cmXMLWriter& xml, { for (std::string const& f : files) { xml.StartElement("Unit"); - xml.Attribute("filename", fsPath + path + "/" + f); + xml.Attribute("filename", cmStrCat(fsPath, path, "/", f)); xml.StartElement("Option"); xml.Attribute("virtualFolder", - "CMake Files\\" + virtualFolderPath + path + "\\"); + cmStrCat("CMake Files\\", virtualFolderPath, path, "\\")); xml.EndElement(); xml.EndElement(); } for (Tree const& folder : folders) { - folder.BuildUnitImpl(xml, virtualFolderPath + path + "\\", - fsPath + path + "/"); + folder.BuildUnitImpl(xml, cmStrCat(virtualFolderPath, path, "\\"), + cmStrCat(fsPath, path, "/")); } } @@ -234,7 +234,7 @@ void cmExtraCodeBlocksGenerator::CreateNewProjectFile( // Also we can disable external (outside the project) files by setting ON // CMAKE_CODEBLOCKS_EXCLUDE_EXTERNAL_FILES variable. const bool excludeExternal = - cmSystemTools::IsOn(it.second[0]->GetMakefile()->GetSafeDefinition( + cmIsOn(it.second[0]->GetMakefile()->GetSafeDefinition( "CMAKE_CODEBLOCKS_EXCLUDE_EXTERNAL_FILES")); if (!splitted.empty() && (!excludeExternal || (relative.find("..") == std::string::npos)) && @@ -318,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; @@ -380,7 +379,7 @@ void cmExtraCodeBlocksGenerator::CreateNewProjectFile( // Do not add this file if it has ".." in relative path and // if CMAKE_CODEBLOCKS_EXCLUDE_EXTERNAL_FILES variable is on. const bool excludeExternal = - cmSystemTools::IsOn(lg->GetMakefile()->GetSafeDefinition( + cmIsOn(lg->GetMakefile()->GetSafeDefinition( "CMAKE_CODEBLOCKS_EXCLUDE_EXTERNAL_FILES")); if (excludeExternal && (relative.find("..") != std::string::npos)) { @@ -412,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; @@ -465,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 */ @@ -490,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); @@ -570,15 +564,13 @@ void cmExtraCodeBlocksGenerator::AppendTarget( std::string systemIncludeDirs = makefile->GetSafeDefinition( "CMAKE_EXTRA_GENERATOR_CXX_SYSTEM_INCLUDE_DIRS"); if (!systemIncludeDirs.empty()) { - cmAppend(allIncludeDirs, - cmSystemTools::ExpandedListArgument(systemIncludeDirs)); + cmAppend(allIncludeDirs, cmExpandedList(systemIncludeDirs)); } systemIncludeDirs = makefile->GetSafeDefinition( "CMAKE_EXTRA_GENERATOR_C_SYSTEM_INCLUDE_DIRS"); if (!systemIncludeDirs.empty()) { - cmAppend(allIncludeDirs, - cmSystemTools::ExpandedListArgument(systemIncludeDirs)); + cmAppend(allIncludeDirs, cmExpandedList(systemIncludeDirs)); } std::vector<std::string>::const_iterator end = diff --git a/Source/cmExtraCodeLiteGenerator.cxx b/Source/cmExtraCodeLiteGenerator.cxx index 6fe8c14..7f71a2c 100644 --- a/Source/cmExtraCodeLiteGenerator.cxx +++ b/Source/cmExtraCodeLiteGenerator.cxx @@ -9,6 +9,7 @@ #include "cmMakefile.h" #include "cmSourceFile.h" #include "cmStateTypes.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmXMLWriter.h" #include "cmake.h" @@ -67,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; } @@ -121,7 +122,7 @@ std::vector<std::string> cmExtraCodeLiteGenerator::CreateProjectsByTarget( cmStateEnums::TargetType type = lt->GetType(); std::string const& outputDir = lg->GetCurrentBinaryDirectory(); std::string targetName = lt->GetName(); - std::string filename = outputDir + "/" + targetName + ".project"; + std::string filename = cmStrCat(outputDir, "/", targetName, ".project"); retval.push_back(targetName); // Make the project file relative to the workspace std::string relafilename = @@ -131,7 +132,7 @@ std::vector<std::string> cmExtraCodeLiteGenerator::CreateProjectsByTarget( case cmStateEnums::SHARED_LIBRARY: case cmStateEnums::STATIC_LIBRARY: case cmStateEnums::MODULE_LIBRARY: - visualname = "lib" + visualname; + visualname = cmStrCat("lib", visualname); CM_FALLTHROUGH; case cmStateEnums::EXECUTABLE: xml->StartElement("Project"); @@ -161,7 +162,7 @@ std::vector<std::string> cmExtraCodeLiteGenerator::CreateProjectsByProjectMaps( std::string const& outputDir = it.second[0]->GetCurrentBinaryDirectory(); std::string projectName = it.second[0]->GetProjectName(); retval.push_back(projectName); - std::string filename = outputDir + "/" + projectName + ".project"; + std::string filename = cmStrCat(outputDir, "/", projectName, ".project"); // Make the project file relative to the workspace filename = cmSystemTools::RelativePath(this->WorkspacePath, filename); @@ -217,22 +218,21 @@ std::string cmExtraCodeLiteGenerator::CollectSourceFiles( case cmStateEnums::STATIC_LIBRARY: case cmStateEnums::SHARED_LIBRARY: case cmStateEnums::MODULE_LIBRARY: { + cmake const* cm = makefile->GetCMakeInstance(); std::vector<cmSourceFile*> sources; gt->GetSourceFiles(sources, makefile->GetSafeDefinition("CMAKE_BUILD_TYPE")); for (cmSourceFile* s : sources) { + std::string const& fullPath = s->GetFullPath(); + std::string const& extLower = + cmSystemTools::LowerCase(s->GetExtension()); // check whether it is a source or a include file // then put it accordingly into one of the two containers - switch (cmSystemTools::GetFileFormat(s->GetExtension())) { - case cmSystemTools::C_FILE_FORMAT: - case cmSystemTools::CXX_FILE_FORMAT: - case cmSystemTools::CUDA_FILE_FORMAT: - case cmSystemTools::FORTRAN_FILE_FORMAT: { - cFiles[s->GetFullPath()] = s; - } break; - default: { - otherFiles.insert(s->GetFullPath()); - } + if (cm->IsSourceExtension(extLower) || cm->IsCudaExtension(extLower) || + cm->IsFortranExtension(extLower)) { + cFiles[fullPath] = s; + } else { + otherFiles.insert(fullPath); } } } @@ -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 aece3bc..6c94aae 100644 --- a/Source/cmExtraEclipseCDT4Generator.cxx +++ b/Source/cmExtraEclipseCDT4Generator.cxx @@ -21,6 +21,7 @@ #include "cmSourceGroup.h" #include "cmState.h" #include "cmStateTypes.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmXMLWriter.h" #include "cmake.h" @@ -44,6 +45,8 @@ void AppendDictionary(cmXMLWriter& xml, const char* key, T const& value) cmExtraEclipseCDT4Generator::cmExtraEclipseCDT4Generator() { + this->IsOutOfSourceBuild = false; + this->GenerateSourceProject = false; this->SupportsVirtualFolders = true; this->GenerateLinkedResources = true; this->SupportsGmakeErrorParser = true; @@ -164,6 +167,29 @@ void cmExtraEclipseCDT4Generator::Generate() // create a .cproject file this->CreateCProjectFile(); + + // create resource settings + this->CreateSettingsResourcePrefsFile(); +} + +void cmExtraEclipseCDT4Generator::CreateSettingsResourcePrefsFile() +{ + cmLocalGenerator* lg = this->GlobalGenerator->GetLocalGenerators()[0]; + cmMakefile* mf = lg->GetMakefile(); + + const std::string filename = + this->HomeOutputDirectory + "/.settings/org.eclipse.core.resources.prefs"; + + cmGeneratedFileStream fout(filename); + if (!fout) { + return; + } + + fout << "eclipse.preferences.version=1" << std::endl; + const char* encoding = mf->GetDefinition("CMAKE_ECLIPSE_RESOURCE_ENCODING"); + if (encoding) { + fout << "encoding/<project>=" << encoding << std::endl; + } } void cmExtraEclipseCDT4Generator::CreateSourceProjectFile() @@ -214,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); @@ -390,8 +415,7 @@ void cmExtraEclipseCDT4Generator::CreateProjectFile() if (const char* extraNaturesProp = mf->GetState()->GetGlobalProperty("ECLIPSE_EXTRA_NATURES")) { - std::vector<std::string> extraNatures; - cmSystemTools::ExpandListArgument(extraNaturesProp, extraNatures); + std::vector<std::string> extraNatures = cmExpandedList(extraNaturesProp); for (std::string const& n : extraNatures) { xml.Element("nature", n); } @@ -438,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(), '\\', '/'); @@ -455,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); @@ -477,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: @@ -540,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), @@ -777,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; - cmSystemTools::ExpandListArgument(cDefs, defs, true); + std::vector<std::string> defs = cmExpandedList(cDefs, true); // the list must contain only definition-value pairs: if ((defs.size() % 2) == 0) { @@ -810,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; - cmSystemTools::ExpandListArgument(cxxDefs, defs, true); + std::vector<std::string> defs = cmExpandedList(cxxDefs, true); // the list must contain only definition-value pairs: if ((defs.size() % 2) == 0) { @@ -861,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; - cmSystemTools::ExpandListArgument(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; - cmSystemTools::ExpandListArgument(systemIncludeDirs, dirs); + std::vector<std::string> dirs = cmExpandedList(systemIncludeDirs); this->AppendIncludeDirectories(xml, dirs, emmited); } @@ -944,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/cmExtraEclipseCDT4Generator.h b/Source/cmExtraEclipseCDT4Generator.h index 5136660..ef038d9 100644 --- a/Source/cmExtraEclipseCDT4Generator.h +++ b/Source/cmExtraEclipseCDT4Generator.h @@ -43,6 +43,9 @@ private: // create .project file in the source tree void CreateSourceProjectFile(); + // create .settings/org.eclipse.core.resources.prefs + void CreateSettingsResourcePrefsFile(); + // create .project file void CreateProjectFile(); 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 71c8fcd..33f5157 100644 --- a/Source/cmExtraSublimeTextGenerator.cxx +++ b/Source/cmExtraSublimeTextGenerator.cxx @@ -17,6 +17,7 @@ #include "cmMessageType.h" #include "cmSourceFile.h" #include "cmStateTypes.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmake.h" @@ -133,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; - cmSystemTools::ExpandListArgument(this->EnvSettings, tokens); + std::vector<std::string> tokens = cmExpandedList(this->EnvSettings); if (!this->EnvSettings.empty()) { fout << ","; @@ -218,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); @@ -266,7 +265,7 @@ void cmExtraSublimeTextGenerator::AppendTarget( R"((^|[ ])-[DIOUWfgs][^= ]+(=\"[^"]+\"|=[^"][^ ]+)?)"; flagRegex.compile(regexString); std::string workString = - flagsString + " " + definesString + " " + includesString; + cmStrCat(flagsString, " ", definesString, " ", includesString); while (flagRegex.find(workString)) { std::string::size_type start = flagRegex.start(); if (workString[start] == ' ') { @@ -310,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); @@ -392,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, @@ -444,7 +442,7 @@ bool cmExtraSublimeTextGenerator::Open(const std::string& bindir, if (!sublExecutable) { return false; } - if (cmSystemTools::IsNOTFOUND(sublExecutable)) { + if (cmIsNOTFOUND(sublExecutable)) { return false; } diff --git a/Source/cmFLTKWrapUICommand.cxx b/Source/cmFLTKWrapUICommand.cxx index 89629c7..2150051 100644 --- a/Source/cmFLTKWrapUICommand.cxx +++ b/Source/cmFLTKWrapUICommand.cxx @@ -8,11 +8,28 @@ #include "cmMakefile.h" #include "cmRange.h" #include "cmSourceFile.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" class cmExecutionStatus; class cmTarget; +static void FinalAction(cmMakefile& makefile, std::string const& name) +{ + // people should add the srcs to the target themselves, but the old command + // didn't support that, so check and see if they added the files in and if + // they didn;t then print a warning and add then anyhow + cmTarget* target = makefile.FindLocalNonAliasTarget(name); + if (!target) { + 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"); + } +} + // cmFLTKWrapUICommand bool cmFLTKWrapUICommand::InitialPass(std::vector<std::string> const& args, cmExecutionStatus&) @@ -27,8 +44,8 @@ bool cmFLTKWrapUICommand::InitialPass(std::vector<std::string> const& args, std::string const& fluid_exe = this->Makefile->GetRequiredDefinition("FLTK_FLUID_EXECUTABLE"); - // get parameter for the command - this->Target = args[0]; // Target that will use the generated files + // Target that will use the generated files + std::string const& target = args[0]; // get the list of GUI files from which .cxx and .h will be generated std::string outputDirectory = this->Makefile->GetCurrentBinaryDirectory(); @@ -41,23 +58,23 @@ bool cmFLTKWrapUICommand::InitialPass(std::vector<std::string> const& args, this->Makefile->AddIncludeDirectories(outputDirectories); } + // List of produced files. + std::vector<cmSourceFile*> generatedSourcesClasses; + for (std::string const& arg : cmMakeRange(args).advance(1)) { cmSourceFile* curr = this->Makefile->GetSource(arg); // if we should use the source GUI // to generate .cxx and .h files if (!curr || !curr->GetPropertyAsBool("WRAP_EXCLUDE")) { - std::string outName = outputDirectory; - outName += "/"; - outName += cmSystemTools::GetFilenameWithoutExtension(arg); - std::string hname = outName; - hname += ".h"; - std::string origname = cdir + "/" + arg; + std::string outName = cmStrCat( + outputDirectory, "/", cmSystemTools::GetFilenameWithoutExtension(arg)); + std::string hname = cmStrCat(outName, ".h"); + std::string origname = cmStrCat(cdir, "/", arg); // add starting depends std::vector<std::string> depends; depends.push_back(origname); depends.push_back(fluid_exe); - std::string cxxres = outName; - cxxres += ".cxx"; + std::string cxxres = cmStrCat(outName, ".cxx"); cmCustomCommandLine commandLine; commandLine.push_back(fluid_exe); @@ -84,40 +101,24 @@ bool cmFLTKWrapUICommand::InitialPass(std::vector<std::string> const& args, cmSourceFile* sf = this->Makefile->GetSource(cxxres); sf->AddDepend(hname); sf->AddDepend(origname); - this->GeneratedSourcesClasses.push_back(sf); + generatedSourcesClasses.push_back(sf); } } // create the variable with the list of sources in it - size_t lastHeadersClass = this->GeneratedSourcesClasses.size(); + size_t lastHeadersClass = generatedSourcesClasses.size(); std::string sourceListValue; for (size_t classNum = 0; classNum < lastHeadersClass; classNum++) { if (classNum) { sourceListValue += ";"; } - sourceListValue += this->GeneratedSourcesClasses[classNum]->GetFullPath(); + sourceListValue += generatedSourcesClasses[classNum]->GetFullPath(); } - std::string varName = this->Target; - varName += "_FLTK_UI_SRCS"; - this->Makefile->AddDefinition(varName, sourceListValue.c_str()); - return true; -} + std::string const varName = target + "_FLTK_UI_SRCS"; + this->Makefile->AddDefinition(varName, sourceListValue); -void cmFLTKWrapUICommand::FinalPass() -{ - // people should add the srcs to the target themselves, but the old command - // didn't support that, so check and see if they added the files in and if - // they didn;t then print a warning and add then anyhow - cmTarget* target = this->Makefile->FindLocalNonAliasTarget(this->Target); - if (!target) { - std::string msg = - "FLTK_WRAP_UI was called with a target that was never created: "; - msg += this->Target; - msg += ". The problem was found while processing the source directory: "; - msg += this->Makefile->GetCurrentSourceDirectory(); - msg += ". This FLTK_WRAP_UI call will be ignored."; - cmSystemTools::Message(msg, "Warning"); - return; - } + this->Makefile->AddFinalAction( + [target](cmMakefile& makefile) { FinalAction(makefile, target); }); + return true; } diff --git a/Source/cmFLTKWrapUICommand.h b/Source/cmFLTKWrapUICommand.h index 044755e..ea8d401 100644 --- a/Source/cmFLTKWrapUICommand.h +++ b/Source/cmFLTKWrapUICommand.h @@ -8,10 +8,11 @@ #include <string> #include <vector> +#include "cm_memory.hxx" + #include "cmCommand.h" class cmExecutionStatus; -class cmSourceFile; /** \class cmFLTKWrapUICommand * \brief Create .h and .cxx files rules for FLTK user interfaces files @@ -25,7 +26,10 @@ public: /** * This is a virtual constructor for the command. */ - cmCommand* Clone() override { return new cmFLTKWrapUICommand; } + std::unique_ptr<cmCommand> Clone() override + { + return cm::make_unique<cmFLTKWrapUICommand>(); + } /** * This is called when the command is first encountered in @@ -33,27 +37,6 @@ public: */ bool InitialPass(std::vector<std::string> const& args, cmExecutionStatus& status) override; - - /** - * This is called at the end after all the information - * specified by the command is accumulated. Most commands do - * not implement this method. At this point, reading and - * writing to the cache can be done. - */ - void FinalPass() override; - bool HasFinalPass() const override { return true; } - -private: - /** - * List of produced files. - */ - std::vector<cmSourceFile*> GeneratedSourcesClasses; - - /** - * List of Fluid files that provide the source - * generating .cxx and .h files - */ - std::string Target; }; #endif diff --git a/Source/cmFileAPI.cxx b/Source/cmFileAPI.cxx index ba42669..5d9181a 100644 --- a/Source/cmFileAPI.cxx +++ b/Source/cmFileAPI.cxx @@ -2,12 +2,12 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmFileAPI.h" -#include "cmAlgorithms.h" #include "cmCryptoHash.h" #include "cmFileAPICMakeFiles.h" #include "cmFileAPICache.h" #include "cmFileAPICodemodel.h" #include "cmGlobalGenerator.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmTimestamp.h" #include "cmake.h" @@ -94,7 +94,7 @@ void cmFileAPI::RemoveOldReplyFiles() std::vector<std::string> files = this->LoadDir(reply_dir); for (std::string const& f : files) { if (this->ReplyFiles.find(f) == this->ReplyFiles.end()) { - std::string file = reply_dir + "/" + f; + std::string file = cmStrCat(reply_dir, "/", f); cmSystemTools::RemoveFile(file); } } @@ -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; } @@ -684,7 +682,6 @@ void cmFileAPI::BuildClientRequestCodeModel( Json::Value cmFileAPI::BuildCodeModel(Object const& object) { - using namespace std::placeholders; Json::Value codemodel = cmFileAPICodemodelDump(*this, object.Version); codemodel["kind"] = this->ObjectKindName(object.Kind); @@ -719,7 +716,6 @@ void cmFileAPI::BuildClientRequestCache( Json::Value cmFileAPI::BuildCache(Object const& object) { - using namespace std::placeholders; Json::Value cache = cmFileAPICacheDump(*this, object.Version); cache["kind"] = this->ObjectKindName(object.Kind); @@ -754,7 +750,6 @@ void cmFileAPI::BuildClientRequestCMakeFiles( Json::Value cmFileAPI::BuildCMakeFiles(Object const& object) { - using namespace std::placeholders; Json::Value cmakeFiles = cmFileAPICMakeFilesDump(*this, object.Version); cmakeFiles["kind"] = this->ObjectKindName(object.Kind); diff --git a/Source/cmFileAPI.h b/Source/cmFileAPI.h index 602efa8..aa5a42f 100644 --- a/Source/cmFileAPI.h +++ b/Source/cmFileAPI.h @@ -10,7 +10,7 @@ #include "cm_jsoncpp_writer.h" #include <map> -#include <memory> // IWYU pragma: keep +#include <memory> #include <string> #include <unordered_set> #include <vector> diff --git a/Source/cmFileAPICodemodel.cxx b/Source/cmFileAPICodemodel.cxx index 6025025..e4b7670 100644 --- a/Source/cmFileAPICodemodel.cxx +++ b/Source/cmFileAPICodemodel.cxx @@ -21,6 +21,7 @@ #include "cmStateDirectory.h" #include "cmStateSnapshot.h" #include "cmStateTypes.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmTarget.h" #include "cmTargetDepend.h" @@ -30,7 +31,11 @@ #include <algorithm> #include <cassert> +#include <cstddef> +#include <functional> +#include <limits> #include <map> +#include <memory> #include <set> #include <string> #include <unordered_map> @@ -134,6 +139,40 @@ std::string TargetId(cmGeneratorTarget const* gt, std::string const& topBuild) return gt->GetName() + CMAKE_DIRECTORY_ID_SEP + hash; } +class JBTIndex +{ +public: + JBTIndex() = default; + explicit operator bool() const { return Index != None; } + Json::ArrayIndex Index = None; + static Json::ArrayIndex const None = static_cast<Json::ArrayIndex>(-1); +}; + +template <typename T> +class JBT +{ +public: + JBT(T v = T(), JBTIndex bt = JBTIndex()) + : Value(std::move(v)) + , Backtrace(bt) + { + } + T Value; + JBTIndex Backtrace; + friend bool operator==(JBT<T> const& l, JBT<T> const& r) + { + return l.Value == r.Value && l.Backtrace.Index == r.Backtrace.Index; + } + static bool ValueEq(JBT<T> const& l, JBT<T> const& r) + { + return l.Value == r.Value; + } + static bool ValueLess(JBT<T> const& l, JBT<T> const& r) + { + return l.Value < r.Value; + } +}; + class BacktraceData { std::string TopSource; @@ -168,7 +207,7 @@ class BacktraceData public: BacktraceData(std::string topSource); - bool Add(cmListFileBacktrace const& bt, Json::ArrayIndex& index); + JBTIndex Add(cmListFileBacktrace const& bt); Json::Value Dump(); }; @@ -177,16 +216,17 @@ BacktraceData::BacktraceData(std::string topSource) { } -bool BacktraceData::Add(cmListFileBacktrace const& bt, Json::ArrayIndex& index) +JBTIndex BacktraceData::Add(cmListFileBacktrace const& bt) { + JBTIndex index; if (bt.Empty()) { - return false; + return index; } cmListFileContext const* top = &bt.Top(); auto found = this->NodeMap.find(top); if (found != this->NodeMap.end()) { - index = found->second; - return true; + index.Index = found->second; + return index; } Json::Value entry = Json::objectValue; entry["file"] = this->AddFile(top->FilePath); @@ -196,13 +236,12 @@ bool BacktraceData::Add(cmListFileBacktrace const& bt, Json::ArrayIndex& index) if (!top->Name.empty()) { entry["command"] = this->AddCommand(top->Name); } - Json::ArrayIndex parent; - if (this->Add(bt.Pop(), parent)) { - entry["parent"] = parent; + if (JBTIndex parent = this->Add(bt.Pop())) { + entry["parent"] = parent.Index; } - index = this->NodeMap[top] = this->Nodes.size(); + index.Index = this->NodeMap[top] = this->Nodes.size(); this->Nodes.append(std::move(entry)); // NOLINT(*) - return true; + return index; } Json::Value BacktraceData::Dump() @@ -221,32 +260,65 @@ struct CompileData { struct IncludeEntry { - BT<std::string> Path; + JBT<std::string> Path; bool IsSystem = false; - IncludeEntry(BT<std::string> path, bool isSystem) + IncludeEntry(JBT<std::string> path, bool isSystem) : Path(std::move(path)) , IsSystem(isSystem) { } + friend bool operator==(IncludeEntry const& l, IncludeEntry const& r) + { + return l.Path == r.Path && l.IsSystem == r.IsSystem; + } }; - void SetDefines(std::set<BT<std::string>> const& defines); - std::string Language; std::string Sysroot; - std::vector<BT<std::string>> Flags; - std::vector<BT<std::string>> Defines; + std::vector<JBT<std::string>> Flags; + std::vector<JBT<std::string>> Defines; std::vector<IncludeEntry> Includes; + + friend bool operator==(CompileData const& l, CompileData const& r) + { + return (l.Language == r.Language && l.Sysroot == r.Sysroot && + l.Flags == r.Flags && l.Defines == r.Defines && + l.Includes == r.Includes); + } }; +} + +namespace std { -void CompileData::SetDefines(std::set<BT<std::string>> const& defines) +template <> +struct hash<CompileData> { - this->Defines.reserve(defines.size()); - for (BT<std::string> const& d : defines) { - this->Defines.push_back(d); + std::size_t operator()(CompileData const& in) const + { + using std::hash; + size_t result = + hash<std::string>()(in.Language) ^ hash<std::string>()(in.Sysroot); + for (auto const& i : in.Includes) { + result = result ^ + (hash<std::string>()(i.Path.Value) ^ + hash<Json::ArrayIndex>()(i.Path.Backtrace.Index) ^ + (i.IsSystem ? std::numeric_limits<size_t>::max() : 0)); + } + for (auto const& i : in.Flags) { + result = result ^ hash<std::string>()(i.Value) ^ + hash<Json::ArrayIndex>()(i.Backtrace.Index); + } + for (auto const& i : in.Defines) { + result = result ^ hash<std::string>()(i.Value) ^ + hash<Json::ArrayIndex>()(i.Backtrace.Index); + } + return result; } -} +}; +} // namespace std + +namespace { class Target { cmGeneratorTarget* GT; @@ -271,24 +343,32 @@ class Target struct CompileGroup { - std::map<Json::Value, Json::ArrayIndex>::iterator Entry; + std::unordered_map<CompileData, Json::ArrayIndex>::iterator Entry; Json::Value SourceIndexes = Json::arrayValue; }; - std::map<Json::Value, Json::ArrayIndex> CompileGroupMap; + std::unordered_map<CompileData, Json::ArrayIndex> CompileGroupMap; std::vector<CompileGroup> CompileGroups; + template <typename T> + JBT<T> ToJBT(BT<T> const& bt) + { + return JBT<T>(bt.Value, this->Backtraces.Add(bt.Backtrace)); + } + void ProcessLanguages(); void ProcessLanguage(std::string const& lang); Json::ArrayIndex AddSourceGroup(cmSourceGroup* sg, Json::ArrayIndex si); CompileData BuildCompileData(cmSourceFile* sf); + CompileData MergeCompileData(CompileData const& fd); Json::ArrayIndex AddSourceCompileGroup(cmSourceFile* sf, Json::ArrayIndex si); void AddBacktrace(Json::Value& object, cmListFileBacktrace const& bt); + void AddBacktrace(Json::Value& object, JBTIndex bt); Json::Value DumpPaths(); - Json::Value DumpCompileData(CompileData cd); + Json::Value DumpCompileData(CompileData const& cd); Json::Value DumpInclude(CompileData::IncludeEntry const& inc); - Json::Value DumpDefine(BT<std::string> const& def); + Json::Value DumpDefine(JBT<std::string> const& def); Json::Value DumpSources(); Json::Value DumpSource(cmGeneratorTarget::SourceAndKind const& sk, Json::ArrayIndex si); @@ -305,8 +385,8 @@ class Target Json::Value DumpLink(); Json::Value DumpArchive(); Json::Value DumpLinkCommandFragments(); - Json::Value DumpCommandFragments(std::vector<BT<std::string>> const& frags); - Json::Value DumpCommandFragment(BT<std::string> const& frag, + Json::Value DumpCommandFragments(std::vector<JBT<std::string>> const& frags); + Json::Value DumpCommandFragment(JBT<std::string> const& frag, std::string const& role = std::string()); Json::Value DumpDependencies(); Json::Value DumpDependency(cmTargetDepend const& td); @@ -721,16 +801,20 @@ void Target::ProcessLanguage(std::string const& lang) // which may need to be factored out. std::string flags; lg->GetTargetCompileFlags(this->GT, this->Config, lang, flags); - cd.Flags.emplace_back(std::move(flags), cmListFileBacktrace()); + cd.Flags.emplace_back(std::move(flags), JBTIndex()); } std::set<BT<std::string>> defines = lg->GetTargetDefines(this->GT, this->Config, lang); - cd.SetDefines(defines); + cd.Defines.reserve(defines.size()); + for (BT<std::string> const& d : defines) { + cd.Defines.emplace_back(this->ToJBT(d)); + } std::vector<BT<std::string>> includePathList = lg->GetIncludeDirectories(this->GT, lang, this->Config); for (BT<std::string> const& i : includePathList) { cd.Includes.emplace_back( - i, this->GT->IsSystemIncludeDirectory(i.Value, this->Config, lang)); + this->ToJBT(i), + this->GT->IsSystemIncludeDirectory(i.Value, this->Config, lang)); } } @@ -757,26 +841,22 @@ CompileData Target::BuildCompileData(cmSourceFile* sf) if (fd.Language.empty()) { return fd; } - CompileData const& cd = this->CompileDataMap.at(fd.Language); - - fd.Sysroot = cd.Sysroot; cmLocalGenerator* lg = this->GT->GetLocalGenerator(); cmGeneratorExpressionInterpreter genexInterpreter(lg, this->Config, this->GT, fd.Language); - fd.Flags = cd.Flags; const std::string COMPILE_FLAGS("COMPILE_FLAGS"); if (const char* cflags = sf->GetProperty(COMPILE_FLAGS)) { std::string flags = genexInterpreter.Evaluate(cflags, COMPILE_FLAGS); - fd.Flags.emplace_back(std::move(flags), cmListFileBacktrace()); + fd.Flags.emplace_back(std::move(flags), JBTIndex()); } const std::string COMPILE_OPTIONS("COMPILE_OPTIONS"); if (const char* coptions = sf->GetProperty(COMPILE_OPTIONS)) { std::string flags; lg->AppendCompileOptions( flags, genexInterpreter.Evaluate(coptions, COMPILE_OPTIONS)); - fd.Flags.emplace_back(std::move(flags), cmListFileBacktrace()); + fd.Flags.emplace_back(std::move(flags), JBTIndex()); } // Add include directories from source file properties. @@ -795,8 +875,6 @@ CompileData Target::BuildCompileData(cmSourceFile* sf) } } } - fd.Includes.insert(fd.Includes.end(), cd.Includes.begin(), - cd.Includes.end()); const std::string COMPILE_DEFINITIONS("COMPILE_DEFINITIONS"); std::set<std::string> fileDefines; @@ -813,27 +891,62 @@ CompileData Target::BuildCompileData(cmSourceFile* sf) genexInterpreter.Evaluate(config_defs, COMPILE_DEFINITIONS)); } - std::set<BT<std::string>> defines; - defines.insert(fileDefines.begin(), fileDefines.end()); - defines.insert(cd.Defines.begin(), cd.Defines.end()); - - fd.SetDefines(defines); + fd.Defines.reserve(fileDefines.size()); + for (std::string const& d : fileDefines) { + fd.Defines.emplace_back(d, JBTIndex()); + } return fd; } +CompileData Target::MergeCompileData(CompileData const& fd) +{ + CompileData cd; + cd.Language = fd.Language; + if (cd.Language.empty()) { + return cd; + } + CompileData const& td = this->CompileDataMap.at(cd.Language); + + // All compile groups share the sysroot of the target. + cd.Sysroot = td.Sysroot; + + // Use target-wide flags followed by source-specific flags. + cd.Flags.reserve(td.Flags.size() + fd.Flags.size()); + cd.Flags.insert(cd.Flags.end(), td.Flags.begin(), td.Flags.end()); + cd.Flags.insert(cd.Flags.end(), fd.Flags.begin(), fd.Flags.end()); + + // Use source-specific includes followed by target-wide includes. + cd.Includes.reserve(fd.Includes.size() + td.Includes.size()); + cd.Includes.insert(cd.Includes.end(), fd.Includes.begin(), + fd.Includes.end()); + cd.Includes.insert(cd.Includes.end(), td.Includes.begin(), + td.Includes.end()); + + // Use target-wide defines followed by source-specific defines. + cd.Defines.reserve(td.Defines.size() + fd.Defines.size()); + cd.Defines.insert(cd.Defines.end(), td.Defines.begin(), td.Defines.end()); + cd.Defines.insert(cd.Defines.end(), fd.Defines.begin(), fd.Defines.end()); + + // De-duplicate defines. + std::stable_sort(cd.Defines.begin(), cd.Defines.end(), + JBT<std::string>::ValueLess); + auto end = std::unique(cd.Defines.begin(), cd.Defines.end(), + JBT<std::string>::ValueEq); + cd.Defines.erase(end, cd.Defines.end()); + + return cd; +} + Json::ArrayIndex Target::AddSourceCompileGroup(cmSourceFile* sf, Json::ArrayIndex si) { - Json::Value compileDataJson = - this->DumpCompileData(this->BuildCompileData(sf)); - std::map<Json::Value, Json::ArrayIndex>::iterator i = - this->CompileGroupMap.find(compileDataJson); + CompileData compileData = this->BuildCompileData(sf); + auto i = this->CompileGroupMap.find(compileData); if (i == this->CompileGroupMap.end()) { Json::ArrayIndex cgIndex = static_cast<Json::ArrayIndex>(this->CompileGroups.size()); - i = - this->CompileGroupMap.emplace(std::move(compileDataJson), cgIndex).first; + i = this->CompileGroupMap.emplace(std::move(compileData), cgIndex).first; CompileGroup g; g.Entry = i; this->CompileGroups.push_back(std::move(g)); @@ -844,9 +957,15 @@ Json::ArrayIndex Target::AddSourceCompileGroup(cmSourceFile* sf, void Target::AddBacktrace(Json::Value& object, cmListFileBacktrace const& bt) { - Json::ArrayIndex backtrace; - if (this->Backtraces.Add(bt, backtrace)) { - object["backtrace"] = backtrace; + if (JBTIndex backtrace = this->Backtraces.Add(bt)) { + object["backtrace"] = backtrace.Index; + } +} + +void Target::AddBacktrace(Json::Value& object, JBTIndex bt) +{ + if (bt) { + object["backtrace"] = bt.Index; } } @@ -914,7 +1033,7 @@ Json::Value Target::DumpSource(cmGeneratorTarget::SourceAndKind const& sk, return source; } -Json::Value Target::DumpCompileData(CompileData cd) +Json::Value Target::DumpCompileData(CompileData const& cd) { Json::Value result = Json::objectValue; @@ -936,7 +1055,7 @@ Json::Value Target::DumpCompileData(CompileData cd) } if (!cd.Defines.empty()) { Json::Value defines = Json::arrayValue; - for (BT<std::string> const& d : cd.Defines) { + for (JBT<std::string> const& d : cd.Defines) { defines.append(this->DumpDefine(d)); } result["defines"] = std::move(defines); @@ -956,7 +1075,7 @@ Json::Value Target::DumpInclude(CompileData::IncludeEntry const& inc) return include; } -Json::Value Target::DumpDefine(BT<std::string> const& def) +Json::Value Target::DumpDefine(JBT<std::string> const& def) { Json::Value define = Json::objectValue; define["define"] = def.Value; @@ -992,7 +1111,8 @@ Json::Value Target::DumpCompileGroups() Json::Value Target::DumpCompileGroup(CompileGroup& cg) { - Json::Value group = cg.Entry->first; + Json::Value group = + this->DumpCompileData(this->MergeCompileData(cg.Entry->first)); group["sourceIndexes"] = std::move(cg.SourceIndexes); return group; } @@ -1072,17 +1192,16 @@ Json::Value Target::DumpArtifacts() } // Add Windows-specific artifacts produced by the linker. + if (this->GT->HasImportLibrary(this->Config)) { + Json::Value artifact = Json::objectValue; + artifact["path"] = + RelativeIfUnder(this->TopBuild, + this->GT->GetFullPath( + this->Config, cmStateEnums::ImportLibraryArtifact)); + artifacts.append(std::move(artifact)); // NOLINT(*) + } if (this->GT->IsDLLPlatform() && this->GT->GetType() != cmStateEnums::STATIC_LIBRARY) { - if (this->GT->GetType() == cmStateEnums::SHARED_LIBRARY || - this->GT->IsExecutableWithExports()) { - Json::Value artifact = Json::objectValue; - artifact["path"] = - RelativeIfUnder(this->TopBuild, - this->GT->GetFullPath( - this->Config, cmStateEnums::ImportLibraryArtifact)); - artifacts.append(std::move(artifact)); // NOLINT(*) - } cmGeneratorTarget::OutputInfo const* output = this->GT->GetOutputInfo(this->Config); if (output && !output->PdbDir.empty()) { @@ -1152,11 +1271,11 @@ Json::Value Target::DumpLinkCommandFragments() lg->GetTargetFlags(&linkLineComputer, this->Config, linkLibs, linkLanguageFlags, linkFlags, frameworkPath, linkPath, this->GT); - linkLanguageFlags = cmSystemTools::TrimWhitespace(linkLanguageFlags); - linkFlags = cmSystemTools::TrimWhitespace(linkFlags); - frameworkPath = cmSystemTools::TrimWhitespace(frameworkPath); - linkPath = cmSystemTools::TrimWhitespace(linkPath); - linkLibs = cmSystemTools::TrimWhitespace(linkLibs); + linkLanguageFlags = cmTrimWhitespace(linkLanguageFlags); + linkFlags = cmTrimWhitespace(linkFlags); + frameworkPath = cmTrimWhitespace(frameworkPath); + linkPath = cmTrimWhitespace(linkPath); + linkLibs = cmTrimWhitespace(linkLibs); if (!linkLanguageFlags.empty()) { linkFragments.append( @@ -1187,16 +1306,16 @@ Json::Value Target::DumpLinkCommandFragments() } Json::Value Target::DumpCommandFragments( - std::vector<BT<std::string>> const& frags) + std::vector<JBT<std::string>> const& frags) { Json::Value commandFragments = Json::arrayValue; - for (BT<std::string> const& f : frags) { + for (JBT<std::string> const& f : frags) { commandFragments.append(this->DumpCommandFragment(f)); } return commandFragments; } -Json::Value Target::DumpCommandFragment(BT<std::string> const& frag, +Json::Value Target::DumpCommandFragment(JBT<std::string> const& frag, std::string const& role) { Json::Value fragment = Json::objectValue; diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx index 7a3954e..5589537 100644 --- a/Source/cmFileCommand.cxx +++ b/Source/cmFileCommand.cxx @@ -12,16 +12,20 @@ #include <assert.h> #include <cmath> #include <ctype.h> -#include <memory> // IWYU pragma: keep +#include <map> +#include <set> #include <sstream> #include <stdio.h> #include <stdlib.h> #include <utility> #include <vector> +#include "cm_memory.hxx" + #include "cmAlgorithms.h" #include "cmArgumentParser.h" #include "cmCryptoHash.h" +#include "cmExecutionStatus.h" #include "cmFileCopier.h" #include "cmFileInstaller.h" #include "cmFileLockPool.h" @@ -34,12 +38,16 @@ #include "cmMessageType.h" #include "cmPolicies.h" #include "cmRange.h" +#include "cmRuntimeDependencyArchive.h" +#include "cmState.h" +#include "cmStringAlgorithms.h" +#include "cmSubcommandTable.h" #include "cmSystemTools.h" #include "cmTimestamp.h" #include "cm_sys_stat.h" #include "cmake.h" -#if defined(CMAKE_BUILD_WITH_CMAKE) +#if !defined(CMAKE_BOOTSTRAP) # include "cmCurl.h" # include "cmFileLockResult.h" # include "cm_curl.h" @@ -53,10 +61,12 @@ # include <windows.h> #endif +namespace { + #if defined(_WIN32) // libcurl doesn't support file:// urls for unicode filenames on Windows. // Convert string from UTF-8 to ACP if this is a file:// URL. -static std::string fix_file_url_windows(const std::string& url) +std::string fix_file_url_windows(const std::string& url) { std::string ret = url; if (strncmp(url.c_str(), "file://", 7) == 0) { @@ -78,120 +88,8 @@ static std::string fix_file_url_windows(const std::string& url) } #endif -// cmLibraryCommand -bool cmFileCommand::InitialPass(std::vector<std::string> const& args, - cmExecutionStatus&) -{ - if (args.size() < 2) { - this->SetError("must be called with at least two arguments."); - return false; - } - std::string const& subCommand = args[0]; - if (subCommand == "WRITE") { - return this->HandleWriteCommand(args, false); - } - if (subCommand == "APPEND") { - return this->HandleWriteCommand(args, true); - } - if (subCommand == "DOWNLOAD") { - return this->HandleDownloadCommand(args); - } - if (subCommand == "UPLOAD") { - return this->HandleUploadCommand(args); - } - if (subCommand == "READ") { - return this->HandleReadCommand(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 == "STRINGS") { - return this->HandleStringsCommand(args); - } - if (subCommand == "GLOB") { - return this->HandleGlobCommand(args, false); - } - if (subCommand == "GLOB_RECURSE") { - return this->HandleGlobCommand(args, true); - } - if (subCommand == "MAKE_DIRECTORY") { - return this->HandleMakeDirectoryCommand(args); - } - if (subCommand == "RENAME") { - return this->HandleRename(args); - } - if (subCommand == "REMOVE") { - return this->HandleRemove(args, false); - } - if (subCommand == "REMOVE_RECURSE") { - return this->HandleRemove(args, true); - } - if (subCommand == "COPY") { - return this->HandleCopyCommand(args); - } - if (subCommand == "INSTALL") { - return this->HandleInstallCommand(args); - } - if (subCommand == "DIFFERENT") { - return this->HandleDifferentCommand(args); - } - if (subCommand == "RPATH_CHANGE" || subCommand == "CHRPATH") { - return this->HandleRPathChangeCommand(args); - } - if (subCommand == "RPATH_CHECK") { - return this->HandleRPathCheckCommand(args); - } - if (subCommand == "RPATH_REMOVE") { - return this->HandleRPathRemoveCommand(args); - } - if (subCommand == "READ_ELF") { - return this->HandleReadElfCommand(args); - } - if (subCommand == "RELATIVE_PATH") { - return this->HandleRelativePathCommand(args); - } - if (subCommand == "TO_CMAKE_PATH") { - return this->HandleCMakePathCommand(args, false); - } - if (subCommand == "TO_NATIVE_PATH") { - return this->HandleCMakePathCommand(args, true); - } - if (subCommand == "TOUCH") { - return this->HandleTouchCommand(args, true); - } - if (subCommand == "TOUCH_NOCREATE") { - return this->HandleTouchCommand(args, false); - } - if (subCommand == "TIMESTAMP") { - return this->HandleTimestampCommand(args); - } - if (subCommand == "GENERATE") { - return this->HandleGenerateCommand(args); - } - if (subCommand == "LOCK") { - return this->HandleLockCommand(args); - } - if (subCommand == "SIZE") { - return this->HandleSizeCommand(args); - } - if (subCommand == "READ_SYMLINK") { - return this->HandleReadSymlinkCommand(args); - } - if (subCommand == "CREATE_LINK") { - return this->HandleCreateLinkCommand(args); - } - - std::string e = "does not recognize sub-command " + subCommand; - this->SetError(e); - return false; -} - -bool cmFileCommand::HandleWriteCommand(std::vector<std::string> const& args, - bool append) +bool HandleWriteImpl(std::vector<std::string> const& args, bool append, + cmExecutionStatus& status) { std::vector<std::string>::const_iterator i = args.begin(); @@ -199,16 +97,16 @@ bool cmFileCommand::HandleWriteCommand(std::vector<std::string> const& args, std::string fileName = *i; if (!cmsys::SystemTools::FileIsFullPath(*i)) { - fileName = this->Makefile->GetCurrentSourceDirectory(); - fileName += "/" + *i; + fileName = + cmStrCat(status.GetMakefile().GetCurrentSourceDirectory(), '/', *i); } i++; - 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; } @@ -236,21 +134,19 @@ bool cmFileCommand::HandleWriteCommand(std::vector<std::string> const& args, 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; - this->SetError(error); + 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; - this->SetError(error); + std::string error = + cmStrCat("write failed (", cmSystemTools::GetLastSystemError(), "):\n ", + fileName); + status.SetError(error); return false; } file.close(); @@ -260,11 +156,24 @@ bool cmFileCommand::HandleWriteCommand(std::vector<std::string> const& args, return true; } -bool cmFileCommand::HandleReadCommand(std::vector<std::string> const& args) +bool HandleWriteCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) +{ + return HandleWriteImpl(args, false, status); +} + +bool HandleAppendCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) +{ + return HandleWriteImpl(args, true, status); +} + +bool HandleReadCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.size() < 3) { - this->SetError("READ must be called with at least two additional " - "arguments"); + status.SetError("READ must be called with at least two additional " + "arguments"); return false; } @@ -287,8 +196,8 @@ bool cmFileCommand::HandleReadCommand(std::vector<std::string> const& args) std::string fileName = fileNameArg; if (!cmsys::SystemTools::FileIsFullPath(fileName)) { - fileName = this->Makefile->GetCurrentSourceDirectory(); - fileName += "/" + fileNameArg; + fileName = cmStrCat(status.GetMakefile().GetCurrentSourceDirectory(), '/', + fileNameArg); } // Open the specified file. @@ -301,11 +210,10 @@ bool cmFileCommand::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; - this->SetError(error); + std::string error = + cmStrCat("failed to open for reading (", + cmSystemTools::GetLastSystemError(), "):\n ", fileName); + status.SetError(error); return false; } @@ -357,53 +265,55 @@ bool cmFileCommand::HandleReadCommand(std::vector<std::string> const& args) } } } - this->Makefile->AddDefinition(variable, output.c_str()); + status.GetMakefile().AddDefinition(variable, output); return true; } -bool cmFileCommand::HandleHashCommand(std::vector<std::string> const& args) +bool HandleHashCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { -#if defined(CMAKE_BUILD_WITH_CMAKE) +#if !defined(CMAKE_BOOTSTRAP) if (args.size() != 3) { std::ostringstream e; e << args[0] << " requires a file name and output variable"; - this->SetError(e.str()); + status.SetError(e.str()); return false; } - std::unique_ptr<cmCryptoHash> hash(cmCryptoHash::New(args[0].c_str())); + std::unique_ptr<cmCryptoHash> hash(cmCryptoHash::New(args[0])); if (hash) { std::string out = hash->HashFile(args[1]); if (!out.empty()) { - this->Makefile->AddDefinition(args[2], out.c_str()); + status.GetMakefile().AddDefinition(args[2], out); return true; } std::ostringstream e; e << args[0] << " failed to read file \"" << args[1] << "\": " << cmSystemTools::GetLastSystemError(); - this->SetError(e.str()); + status.SetError(e.str()); } return false; #else std::ostringstream e; e << args[0] << " not available during bootstrap"; - this->SetError(e.str()); + status.SetError(e.str()); return false; #endif } -bool cmFileCommand::HandleStringsCommand(std::vector<std::string> const& args) +bool HandleStringsCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.size() < 3) { - this->SetError("STRINGS requires a file name and output variable"); + status.SetError("STRINGS requires a file name and output variable"); return false; } // Get the file to read. std::string fileName = args[1]; if (!cmsys::SystemTools::FileIsFullPath(fileName)) { - fileName = this->Makefile->GetCurrentSourceDirectory(); - fileName += "/" + args[1]; + fileName = + cmStrCat(status.GetMakefile().GetCurrentSourceDirectory(), '/', args[1]); } // Get the variable in which to store the results. @@ -469,7 +379,7 @@ bool cmFileCommand::HandleStringsCommand(std::vector<std::string> const& args) std::ostringstream e; e << "STRINGS option LIMIT_INPUT value \"" << args[i] << "\" is not an unsigned integer."; - this->SetError(e.str()); + status.SetError(e.str()); return false; } arg_mode = arg_none; @@ -479,7 +389,7 @@ bool cmFileCommand::HandleStringsCommand(std::vector<std::string> const& args) std::ostringstream e; e << "STRINGS option LIMIT_OUTPUT value \"" << args[i] << "\" is not an unsigned integer."; - this->SetError(e.str()); + status.SetError(e.str()); return false; } arg_mode = arg_none; @@ -489,7 +399,7 @@ bool cmFileCommand::HandleStringsCommand(std::vector<std::string> const& args) std::ostringstream e; e << "STRINGS option LIMIT_COUNT value \"" << args[i] << "\" is not an unsigned integer."; - this->SetError(e.str()); + status.SetError(e.str()); return false; } limit_count = count; @@ -500,7 +410,7 @@ bool cmFileCommand::HandleStringsCommand(std::vector<std::string> const& args) std::ostringstream e; e << "STRINGS option LENGTH_MINIMUM value \"" << args[i] << "\" is not an unsigned integer."; - this->SetError(e.str()); + status.SetError(e.str()); return false; } minlen = len; @@ -511,7 +421,7 @@ bool cmFileCommand::HandleStringsCommand(std::vector<std::string> const& args) std::ostringstream e; e << "STRINGS option LENGTH_MAXIMUM value \"" << args[i] << "\" is not an unsigned integer."; - this->SetError(e.str()); + status.SetError(e.str()); return false; } maxlen = len; @@ -521,7 +431,7 @@ bool cmFileCommand::HandleStringsCommand(std::vector<std::string> const& args) std::ostringstream e; e << "STRINGS option REGEX value \"" << args[i] << "\" could not be compiled."; - this->SetError(e.str()); + status.SetError(e.str()); return false; } have_regex = true; @@ -540,23 +450,23 @@ bool cmFileCommand::HandleStringsCommand(std::vector<std::string> const& args) } else { std::ostringstream e; e << "STRINGS option ENCODING \"" << args[i] << "\" not recognized."; - this->SetError(e.str()); + status.SetError(e.str()); return false; } arg_mode = arg_none; } else { std::ostringstream e; e << "STRINGS given unknown argument \"" << args[i] << "\""; - this->SetError(e.str()); + status.SetError(e.str()); return false; } } if (hex_conversion_enabled) { // TODO: should work without temp file, but just on a memory buffer - std::string binaryFileName = this->Makefile->GetCurrentBinaryDirectory(); - binaryFileName += "/CMakeFiles"; - binaryFileName += "/FileCommandStringsBinaryFile"; + std::string binaryFileName = + cmStrCat(status.GetMakefile().GetCurrentBinaryDirectory(), + "/CMakeFiles/FileCommandStringsBinaryFile"); if (cmHexFileConverter::TryConvert(fileName, binaryFileName)) { fileName = binaryFileName; } @@ -571,7 +481,7 @@ bool cmFileCommand::HandleStringsCommand(std::vector<std::string> const& args) if (!fin) { std::ostringstream e; e << "STRINGS file \"" << fileName << "\" cannot be read."; - this->SetError(e.str()); + status.SetError(e.str()); return false; } @@ -743,12 +653,12 @@ bool cmFileCommand::HandleStringsCommand(std::vector<std::string> const& args) } // Save the output in a makefile variable. - this->Makefile->AddDefinition(outVar, output.c_str()); + status.GetMakefile().AddDefinition(outVar, output); return true; } -bool cmFileCommand::HandleGlobCommand(std::vector<std::string> const& args, - bool recurse) +bool HandleGlobImpl(std::vector<std::string> const& args, bool recurse, + cmExecutionStatus& status) { // File commands has at least one argument assert(args.size() > 1); @@ -763,10 +673,10 @@ bool cmFileCommand::HandleGlobCommand(std::vector<std::string> const& args, g.SetRecurse(recurse); bool explicitFollowSymlinks = false; - cmPolicies::PolicyStatus status = - this->Makefile->GetPolicyStatus(cmPolicies::CMP0009); + cmPolicies::PolicyStatus policyStatus = + status.GetMakefile().GetPolicyStatus(cmPolicies::CMP0009); if (recurse) { - switch (status) { + switch (policyStatus) { case cmPolicies::REQUIRED_IF_USED: case cmPolicies::REQUIRED_ALWAYS: case cmPolicies::NEW: @@ -784,24 +694,24 @@ bool cmFileCommand::HandleGlobCommand(std::vector<std::string> const& args, bool warnConfigureLate = false; bool warnFollowedSymlinks = false; const cmake::WorkingMode workingMode = - this->Makefile->GetCMakeInstance()->GetWorkingMode(); + status.GetMakefile().GetCMakeInstance()->GetWorkingMode(); while (i != args.end()) { if (*i == "LIST_DIRECTORIES") { ++i; // skip LIST_DIRECTORIES if (i != args.end()) { - if (cmSystemTools::IsOn(*i)) { + if (cmIsOn(*i)) { g.SetListDirs(true); g.SetRecurseListDirs(true); - } else if (cmSystemTools::IsOff(*i)) { + } else if (cmIsOff(*i)) { g.SetListDirs(false); g.SetRecurseListDirs(false); } else { - this->SetError("LIST_DIRECTORIES missing bool value."); + status.SetError("LIST_DIRECTORIES missing bool value."); return false; } ++i; } else { - this->SetError("LIST_DIRECTORIES missing bool value."); + status.SetError("LIST_DIRECTORIES missing bool value."); return false; } } else if (*i == "FOLLOW_SYMLINKS") { @@ -810,7 +720,7 @@ bool cmFileCommand::HandleGlobCommand(std::vector<std::string> const& args, explicitFollowSymlinks = true; g.RecurseThroughSymlinksOn(); if (i == args.end()) { - this->SetError( + status.SetError( "GLOB_RECURSE requires a glob expression after FOLLOW_SYMLINKS."); return false; } @@ -818,25 +728,26 @@ bool cmFileCommand::HandleGlobCommand(std::vector<std::string> const& args, } else if (*i == "RELATIVE") { ++i; // skip RELATIVE if (i == args.end()) { - this->SetError("GLOB requires a directory after the RELATIVE tag."); + status.SetError("GLOB requires a directory after the RELATIVE tag."); return false; } g.SetRelative(i->c_str()); ++i; if (i == args.end()) { - this->SetError("GLOB requires a glob expression after the directory."); + status.SetError( + "GLOB requires a glob expression after the directory."); return false; } } else if (*i == "CONFIGURE_DEPENDS") { // Generated build system depends on glob results if (!configureDepends && warnConfigureLate) { - this->Makefile->IssueMessage( + status.GetMakefile().IssueMessage( MessageType::AUTHOR_WARNING, "CONFIGURE_DEPENDS flag was given after a glob expression was " "already evaluated."); } if (workingMode != cmake::NORMAL_MODE) { - this->Makefile->IssueMessage( + status.GetMakefile().IssueMessage( MessageType::FATAL_ERROR, "CONFIGURE_DEPENDS is invalid for script and find package modes."); return false; @@ -844,14 +755,14 @@ bool cmFileCommand::HandleGlobCommand(std::vector<std::string> const& args, configureDepends = true; ++i; if (i == args.end()) { - this->SetError( + status.SetError( "GLOB requires a glob expression after CONFIGURE_DEPENDS."); return false; } } else { std::string expr = *i; if (!cmsys::SystemTools::FileIsFullPath(*i)) { - expr = this->Makefile->GetCurrentSourceDirectory(); + expr = status.GetMakefile().GetCurrentSourceDirectory(); // Handle script mode if (!expr.empty()) { expr += "/" + *i; @@ -867,12 +778,12 @@ bool cmFileCommand::HandleGlobCommand(std::vector<std::string> const& args, bool shouldExit = false; for (cmsys::Glob::Message const& globMessage : globMessages) { if (globMessage.type == cmsys::Glob::cyclicRecursion) { - this->Makefile->IssueMessage( + status.GetMakefile().IssueMessage( MessageType::AUTHOR_WARNING, "Cyclic recursion detected while globbing for '" + *i + "':\n" + globMessage.content); } else { - this->Makefile->IssueMessage( + status.GetMakefile().IssueMessage( MessageType::FATAL_ERROR, "Error has occurred while globbing for '" + *i + "' - " + globMessage.content); @@ -896,11 +807,11 @@ bool cmFileCommand::HandleGlobCommand(std::vector<std::string> const& args, std::sort(foundFiles.begin(), foundFiles.end()); foundFiles.erase(std::unique(foundFiles.begin(), foundFiles.end()), foundFiles.end()); - this->Makefile->GetCMakeInstance()->AddGlobCacheEntry( + status.GetMakefile().GetCMakeInstance()->AddGlobCacheEntry( recurse, (recurse ? g.GetRecurseListDirs() : g.GetListDirs()), (recurse ? g.GetRecurseThroughSymlinks() : false), (g.GetRelative() ? g.GetRelative() : ""), expr, foundFiles, variable, - this->Makefile->GetBacktrace()); + status.GetMakefile().GetBacktrace()); } else { warnConfigureLate = true; } @@ -908,7 +819,7 @@ bool cmFileCommand::HandleGlobCommand(std::vector<std::string> const& args, } } - switch (status) { + switch (policyStatus) { case cmPolicies::REQUIRED_IF_USED: case cmPolicies::REQUIRED_ALWAYS: case cmPolicies::NEW: @@ -921,7 +832,7 @@ bool cmFileCommand::HandleGlobCommand(std::vector<std::string> const& args, // Possibly unexpected old behavior *and* we actually traversed // symlinks without being explicitly asked to: warn the author. if (warnFollowedSymlinks) { - this->Makefile->IssueMessage( + status.GetMakefile().IssueMessage( MessageType::AUTHOR_WARNING, cmPolicies::GetPolicyWarning(cmPolicies::CMP0009)); } @@ -930,12 +841,24 @@ bool cmFileCommand::HandleGlobCommand(std::vector<std::string> const& args, std::sort(files.begin(), files.end()); files.erase(std::unique(files.begin(), files.end()), files.end()); - this->Makefile->AddDefinition(variable, cmJoin(files, ";").c_str()); + status.GetMakefile().AddDefinition(variable, cmJoin(files, ";")); return true; } -bool cmFileCommand::HandleMakeDirectoryCommand( - std::vector<std::string> const& args) +bool HandleGlobCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) +{ + return HandleGlobImpl(args, false, status); +} + +bool HandleGlobRecurseCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) +{ + return HandleGlobImpl(args, true, status); +} + +bool HandleMakeDirectoryCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { // File command has at least one argument assert(args.size() > 1); @@ -946,28 +869,28 @@ bool cmFileCommand::HandleMakeDirectoryCommand( { const std::string* cdir = &arg; if (!cmsys::SystemTools::FileIsFullPath(arg)) { - expr = this->Makefile->GetCurrentSourceDirectory(); - expr += "/" + arg; + expr = + cmStrCat(status.GetMakefile().GetCurrentSourceDirectory(), '/', arg); cdir = &expr; } - if (!this->Makefile->CanIWriteThisFile(*cdir)) { + if (!status.GetMakefile().CanIWriteThisFile(*cdir)) { std::string e = "attempted to create a directory: " + *cdir + " into a source directory."; - this->SetError(e); + status.SetError(e); cmSystemTools::SetFatalErrorOccured(); return false; } if (!cmSystemTools::MakeDirectory(*cdir)) { std::string error = "problem creating directory: " + *cdir; - this->SetError(error); + status.SetError(error); return false; } } return true; } -bool cmFileCommand::HandleTouchCommand(std::vector<std::string> const& args, - bool create) +bool HandleTouchImpl(std::vector<std::string> const& args, bool create, + cmExecutionStatus& status) { // File command has at least one argument assert(args.size() > 1); @@ -977,27 +900,39 @@ bool cmFileCommand::HandleTouchCommand(std::vector<std::string> const& args, { std::string tfile = arg; if (!cmsys::SystemTools::FileIsFullPath(tfile)) { - tfile = this->Makefile->GetCurrentSourceDirectory(); - tfile += "/" + arg; + tfile = + cmStrCat(status.GetMakefile().GetCurrentSourceDirectory(), '/', arg); } - if (!this->Makefile->CanIWriteThisFile(tfile)) { + if (!status.GetMakefile().CanIWriteThisFile(tfile)) { std::string e = "attempted to touch a file: " + tfile + " in a source directory."; - this->SetError(e); + status.SetError(e); cmSystemTools::SetFatalErrorOccured(); return false; } if (!cmSystemTools::Touch(tfile, create)) { std::string error = "problem touching file: " + tfile; - this->SetError(error); + status.SetError(error); return false; } } return true; } -bool cmFileCommand::HandleDifferentCommand( - std::vector<std::string> const& args) +bool HandleTouchCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) +{ + return HandleTouchImpl(args, true, status); +} + +bool HandleTouchNocreateCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) +{ + return HandleTouchImpl(args, false, status); +} + +bool HandleDifferentCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { /* FILE(DIFFERENT <variable> FILES <lhs> <rhs>) @@ -1030,39 +965,41 @@ bool cmFileCommand::HandleDifferentCommand( } else { std::ostringstream e; e << "DIFFERENT given unknown argument " << args[i]; - this->SetError(e.str()); + status.SetError(e.str()); return false; } } if (!var) { - this->SetError("DIFFERENT not given result variable name."); + status.SetError("DIFFERENT not given result variable name."); return false; } if (!file_lhs || !file_rhs) { - this->SetError("DIFFERENT not given FILES option with two file names."); + status.SetError("DIFFERENT not given FILES option with two file names."); return false; } // Compare the files. const char* result = cmSystemTools::FilesDiffer(file_lhs, file_rhs) ? "1" : "0"; - this->Makefile->AddDefinition(var, result); + status.GetMakefile().AddDefinition(var, result); return true; } -bool cmFileCommand::HandleCopyCommand(std::vector<std::string> const& args) +bool HandleCopyCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { - cmFileCopier copier(this); + cmFileCopier copier(status); return copier.Run(args); } -bool cmFileCommand::HandleRPathChangeCommand( - std::vector<std::string> const& args) +bool HandleRPathChangeCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { // Evaluate arguments. std::string file; const char* oldRPath = nullptr; const char* newRPath = nullptr; + bool removeEnvironmentRPath = false; enum Doing { DoingNone, @@ -1078,6 +1015,8 @@ bool cmFileCommand::HandleRPathChangeCommand( doing = DoingNew; } else if (args[i] == "FILE") { doing = DoingFile; + } else if (args[i] == "INSTALL_REMOVE_ENVIRONMENT_RPATH") { + removeEnvironmentRPath = true; } else if (doing == DoingFile) { file = args[i]; doing = DoingNone; @@ -1090,33 +1029,35 @@ bool cmFileCommand::HandleRPathChangeCommand( } else { std::ostringstream e; e << "RPATH_CHANGE given unknown argument " << args[i]; - this->SetError(e.str()); + status.SetError(e.str()); return false; } } if (file.empty()) { - this->SetError("RPATH_CHANGE not given FILE option."); + status.SetError("RPATH_CHANGE not given FILE option."); return false; } if (!oldRPath) { - this->SetError("RPATH_CHANGE not given OLD_RPATH option."); + status.SetError("RPATH_CHANGE not given OLD_RPATH option."); return false; } if (!newRPath) { - this->SetError("RPATH_CHANGE not given NEW_RPATH option."); + status.SetError("RPATH_CHANGE not given NEW_RPATH option."); return false; } if (!cmSystemTools::FileExists(file, true)) { std::ostringstream e; e << "RPATH_CHANGE given FILE \"" << file << "\" that does not exist."; - this->SetError(e.str()); + status.SetError(e.str()); return false; } bool success = true; cmFileTimes const ft(file); std::string emsg; bool changed; - if (!cmSystemTools::ChangeRPath(file, oldRPath, newRPath, &emsg, &changed)) { + + if (!cmSystemTools::ChangeRPath(file, oldRPath, newRPath, + removeEnvironmentRPath, &emsg, &changed)) { std::ostringstream e; /* clang-format off */ e << "RPATH_CHANGE could not write new RPATH:\n" @@ -1125,25 +1066,22 @@ bool cmFileCommand::HandleRPathChangeCommand( << " " << file << "\n" << emsg; /* clang-format on */ - this->SetError(e.str()); + status.SetError(e.str()); success = false; } if (success) { if (changed) { - std::string message = "Set runtime path of \""; - message += file; - message += "\" to \""; - message += newRPath; - message += "\""; - this->Makefile->DisplayStatus(message, -1); + std::string message = + cmStrCat("Set runtime path of \"", file, "\" to \"", newRPath, '"'); + status.GetMakefile().DisplayStatus(message, -1); } ft.Store(file); } return success; } -bool cmFileCommand::HandleRPathRemoveCommand( - std::vector<std::string> const& args) +bool HandleRPathRemoveCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { // Evaluate arguments. std::string file; @@ -1162,18 +1100,18 @@ bool cmFileCommand::HandleRPathRemoveCommand( } else { std::ostringstream e; e << "RPATH_REMOVE given unknown argument " << args[i]; - this->SetError(e.str()); + status.SetError(e.str()); return false; } } if (file.empty()) { - this->SetError("RPATH_REMOVE not given FILE option."); + status.SetError("RPATH_REMOVE not given FILE option."); return false; } if (!cmSystemTools::FileExists(file, true)) { std::ostringstream e; e << "RPATH_REMOVE given FILE \"" << file << "\" that does not exist."; - this->SetError(e.str()); + status.SetError(e.str()); return false; } bool success = true; @@ -1187,23 +1125,22 @@ bool cmFileCommand::HandleRPathRemoveCommand( << " " << file << "\n" << emsg; /* clang-format on */ - this->SetError(e.str()); + status.SetError(e.str()); success = false; } if (success) { if (removed) { - std::string message = "Removed runtime path from \""; - message += file; - message += "\""; - this->Makefile->DisplayStatus(message, -1); + std::string message = + cmStrCat("Removed runtime path from \"", file, '"'); + status.GetMakefile().DisplayStatus(message, -1); } ft.Store(file); } return success; } -bool cmFileCommand::HandleRPathCheckCommand( - std::vector<std::string> const& args) +bool HandleRPathCheckCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { // Evaluate arguments. std::string file; @@ -1229,16 +1166,16 @@ bool cmFileCommand::HandleRPathCheckCommand( } else { std::ostringstream e; e << "RPATH_CHECK given unknown argument " << args[i]; - this->SetError(e.str()); + status.SetError(e.str()); return false; } } if (file.empty()) { - this->SetError("RPATH_CHECK not given FILE option."); + status.SetError("RPATH_CHECK not given FILE option."); return false; } if (!rpath) { - this->SetError("RPATH_CHECK not given RPATH option."); + status.SetError("RPATH_CHECK not given RPATH option."); return false; } @@ -1253,11 +1190,12 @@ bool cmFileCommand::HandleRPathCheckCommand( return true; } -bool cmFileCommand::HandleReadElfCommand(std::vector<std::string> const& args) +bool HandleReadElfCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.size() < 4) { - this->SetError("READ_ELF must be called with at least three additional " - "arguments."); + status.SetError("READ_ELF must be called with at least three additional " + "arguments."); return false; } @@ -1279,7 +1217,7 @@ bool cmFileCommand::HandleReadElfCommand(std::vector<std::string> const& args) if (!cmSystemTools::FileExists(fileNameArg, true)) { std::ostringstream e; e << "READ_ELF given FILE \"" << fileNameArg << "\" that does not exist."; - this->SetError(e.str()); + status.SetError(e.str()); return false; } @@ -1290,14 +1228,14 @@ bool cmFileCommand::HandleReadElfCommand(std::vector<std::string> const& args) if (cmELF::StringEntry const* se_rpath = elf.GetRPath()) { std::string rpath(se_rpath->Value); std::replace(rpath.begin(), rpath.end(), ':', ';'); - this->Makefile->AddDefinition(arguments.RPath, rpath.c_str()); + status.GetMakefile().AddDefinition(arguments.RPath, rpath); } } if (!arguments.RunPath.empty()) { if (cmELF::StringEntry const* se_runpath = elf.GetRunPath()) { std::string runpath(se_runpath->Value); std::replace(runpath.begin(), runpath.end(), ':', ';'); - this->Makefile->AddDefinition(arguments.RunPath, runpath.c_str()); + status.GetMakefile().AddDefinition(arguments.RunPath, runpath); } } @@ -1305,25 +1243,26 @@ bool cmFileCommand::HandleReadElfCommand(std::vector<std::string> const& args) #else std::string error = "ELF parser not available on this platform."; if (arguments.Error.empty()) { - this->SetError(error); + status.SetError(error); return false; } - this->Makefile->AddDefinition(arguments.Error, error.c_str()); + status.GetMakefile().AddDefinition(arguments.Error, error); return true; #endif } -bool cmFileCommand::HandleInstallCommand(std::vector<std::string> const& args) +bool HandleInstallCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { - cmFileInstaller installer(this); + cmFileInstaller installer(status); return installer.Run(args); } -bool cmFileCommand::HandleRelativePathCommand( - std::vector<std::string> const& args) +bool HandleRelativePathCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.size() != 4) { - this->SetError("RELATIVE_PATH called with incorrect number of arguments"); + status.SetError("RELATIVE_PATH called with incorrect number of arguments"); return false; } @@ -1335,38 +1274,39 @@ bool cmFileCommand::HandleRelativePathCommand( std::string errstring = "RELATIVE_PATH must be passed a full path to the directory: " + directoryName; - this->SetError(errstring); + status.SetError(errstring); return false; } if (!cmSystemTools::FileIsFullPath(fileName)) { std::string errstring = "RELATIVE_PATH must be passed a full path to the file: " + fileName; - this->SetError(errstring); + status.SetError(errstring); return false; } std::string res = cmSystemTools::RelativePath(directoryName, fileName); - this->Makefile->AddDefinition(outVar, res.c_str()); + status.GetMakefile().AddDefinition(outVar, res); return true; } -bool cmFileCommand::HandleRename(std::vector<std::string> const& args) +bool HandleRename(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.size() != 3) { - this->SetError("RENAME given incorrect number of arguments."); + status.SetError("RENAME given incorrect number of arguments."); return false; } // Compute full path for old and new names. std::string oldname = args[1]; if (!cmsys::SystemTools::FileIsFullPath(oldname)) { - oldname = this->Makefile->GetCurrentSourceDirectory(); - oldname += "/" + args[1]; + oldname = + cmStrCat(status.GetMakefile().GetCurrentSourceDirectory(), '/', args[1]); } std::string newname = args[2]; if (!cmsys::SystemTools::FileIsFullPath(newname)) { - newname = this->Makefile->GetCurrentSourceDirectory(); - newname += "/" + args[2]; + newname = + cmStrCat(status.GetMakefile().GetCurrentSourceDirectory(), '/', args[2]); } if (!cmSystemTools::RenameFile(oldname, newname)) { @@ -1379,14 +1319,14 @@ bool cmFileCommand::HandleRename(std::vector<std::string> const& args) << " " << newname << "\n" << "because: " << err << "\n"; /* clang-format on */ - this->SetError(e.str()); + status.SetError(e.str()); return false; } return true; } -bool cmFileCommand::HandleRemove(std::vector<std::string> const& args, - bool recurse) +bool HandleRemoveImpl(std::vector<std::string> const& args, bool recurse, + cmExecutionStatus& status) { std::string message; @@ -1397,18 +1337,18 @@ bool cmFileCommand::HandleRemove(std::vector<std::string> const& args, std::string fileName = arg; if (fileName.empty()) { std::string const r = recurse ? "REMOVE_RECURSE" : "REMOVE"; - this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, - "Ignoring empty file name in " + r + "."); + status.GetMakefile().IssueMessage( + MessageType::AUTHOR_WARNING, "Ignoring empty file name in " + r + "."); continue; } if (!cmsys::SystemTools::FileIsFullPath(fileName)) { - fileName = this->Makefile->GetCurrentSourceDirectory(); - fileName += "/" + arg; + fileName = + cmStrCat(status.GetMakefile().GetCurrentSourceDirectory(), '/', arg); } if (cmSystemTools::FileIsDirectory(fileName) && !cmSystemTools::FileIsSymlink(fileName) && recurse) { - cmSystemTools::RemoveADirectory(fileName); + cmSystemTools::RepeatedRemoveDirectory(fileName); } else { cmSystemTools::RemoveFile(fileName); } @@ -1416,7 +1356,18 @@ bool cmFileCommand::HandleRemove(std::vector<std::string> const& args, return true; } -namespace { +bool HandleRemove(std::vector<std::string> const& args, + cmExecutionStatus& status) +{ + return HandleRemoveImpl(args, false, status); +} + +bool HandleRemoveRecurse(std::vector<std::string> const& args, + cmExecutionStatus& status) +{ + return HandleRemoveImpl(args, true, status); +} + std::string ToNativePath(const std::string& path) { const auto& outPath = cmSystemTools::ConvertToOutputPath(path); @@ -1433,14 +1384,14 @@ std::string ToCMakePath(const std::string& path) cmSystemTools::ConvertToUnixSlashes(temp); return temp; } -} -bool cmFileCommand::HandleCMakePathCommand( - std::vector<std::string> const& args, bool nativePath) +bool HandlePathCommand(std::vector<std::string> const& args, + std::string (*convert)(std::string const&), + cmExecutionStatus& status) { if (args.size() != 3) { - this->SetError("FILE([TO_CMAKE_PATH|TO_NATIVE_PATH] path result) must be " - "called with exactly three arguments."); + status.SetError("FILE([TO_CMAKE_PATH|TO_NATIVE_PATH] path result) must be " + "called with exactly three arguments."); return false; } #if defined(_WIN32) && !defined(__CYGWIN__) @@ -1450,19 +1401,28 @@ bool cmFileCommand::HandleCMakePathCommand( #endif std::vector<std::string> path = cmSystemTools::SplitString(args[1], pathSep); - std::string value = cmJoin( - cmMakeRange(path).transform(nativePath ? ToNativePath : ToCMakePath), ";"); - this->Makefile->AddDefinition(args[2], value.c_str()); + std::string value = cmJoin(cmMakeRange(path).transform(convert), ";"); + status.GetMakefile().AddDefinition(args[2], value); return true; } -#if defined(CMAKE_BUILD_WITH_CMAKE) +bool HandleCMakePathCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) +{ + return HandlePathCommand(args, ToCMakePath, status); +} + +bool HandleNativePathCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) +{ + return HandlePathCommand(args, ToNativePath, status); +} + +#if !defined(CMAKE_BOOTSTRAP) // Stuff for curl download/upload typedef std::vector<char> cmFileCommandVectorOfChar; -namespace { - size_t cmWriteToFileCallback(void* ptr, size_t size, size_t nmemb, void* data) { int realsize = static_cast<int>(size * nmemb); @@ -1513,11 +1473,10 @@ size_t cmFileCommandCurlDebugCallback(CURL*, curl_infotype type, char* chPtr, class cURLProgressHelper { public: - cURLProgressHelper(cmFileCommand* fc, const char* text) + cURLProgressHelper(cmMakefile* mf, const char* text) + : Makefile(mf) + , Text(text) { - this->CurrentPercentage = -1; - this->FileCommand = fc; - this->Text = text; } bool UpdatePercentage(double value, double total, std::string& status) @@ -1544,11 +1503,11 @@ public: return updated; } - cmFileCommand* GetFileCommand() { return this->FileCommand; } + cmMakefile* GetMakefile() { return this->Makefile; } private: - long CurrentPercentage; - cmFileCommand* FileCommand; + long CurrentPercentage = -1; + cmMakefile* Makefile; std::string Text; }; @@ -1562,8 +1521,7 @@ int cmFileDownloadProgressCallback(void* clientp, double dltotal, double dlnow, std::string status; if (helper->UpdatePercentage(dlnow, dltotal, status)) { - cmFileCommand* fc = helper->GetFileCommand(); - cmMakefile* mf = fc->GetMakefile(); + cmMakefile* mf = helper->GetMakefile(); mf->DisplayStatus(status, -1); } @@ -1580,16 +1538,12 @@ int cmFileUploadProgressCallback(void* clientp, double dltotal, double dlnow, std::string status; if (helper->UpdatePercentage(ulnow, ultotal, status)) { - cmFileCommand* fc = helper->GetFileCommand(); - cmMakefile* mf = fc->GetMakefile(); + cmMakefile* mf = helper->GetMakefile(); mf->DisplayStatus(status, -1); } return 0; } -} - -namespace { class cURLEasyGuard { @@ -1614,7 +1568,7 @@ public: private: ::CURL* Easy; }; -} + #endif #define check_curl_result(result, errstr) \ @@ -1622,17 +1576,18 @@ private: if (result != CURLE_OK) { \ std::string e(errstr); \ e += ::curl_easy_strerror(result); \ - this->SetError(e); \ + status.SetError(e); \ return false; \ } \ } while (false) -bool cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args) +bool HandleDownloadCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { -#if defined(CMAKE_BUILD_WITH_CMAKE) +#if !defined(CMAKE_BOOTSTRAP) std::vector<std::string>::const_iterator i = args.begin(); if (args.size() < 3) { - this->SetError("DOWNLOAD must be called with at least three arguments."); + status.SetError("DOWNLOAD must be called with at least three arguments."); return false; } ++i; // Get rid of subcommand @@ -1645,11 +1600,12 @@ bool cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args) long inactivity_timeout = 0; std::string logVar; std::string statusVar; - bool tls_verify = this->Makefile->IsOn("CMAKE_TLS_VERIFY"); - const char* cainfo = this->Makefile->GetDefinition("CMAKE_TLS_CAINFO"); - std::string netrc_level = this->Makefile->GetSafeDefinition("CMAKE_NETRC"); + bool tls_verify = status.GetMakefile().IsOn("CMAKE_TLS_VERIFY"); + const char* cainfo = status.GetMakefile().GetDefinition("CMAKE_TLS_CAINFO"); + std::string netrc_level = + status.GetMakefile().GetSafeDefinition("CMAKE_NETRC"); std::string netrc_file = - this->Makefile->GetSafeDefinition("CMAKE_NETRC_FILE"); + status.GetMakefile().GetSafeDefinition("CMAKE_NETRC_FILE"); std::string expectedHash; std::string hashMatchMSG; std::unique_ptr<cmCryptoHash> hash; @@ -1664,7 +1620,7 @@ bool cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args) if (i != args.end()) { timeout = atol(i->c_str()); } else { - this->SetError("DOWNLOAD missing time for TIMEOUT."); + status.SetError("DOWNLOAD missing time for TIMEOUT."); return false; } } else if (*i == "INACTIVITY_TIMEOUT") { @@ -1672,29 +1628,29 @@ bool cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args) if (i != args.end()) { inactivity_timeout = atol(i->c_str()); } else { - this->SetError("DOWNLOAD missing time for INACTIVITY_TIMEOUT."); + status.SetError("DOWNLOAD missing time for INACTIVITY_TIMEOUT."); return false; } } else if (*i == "LOG") { ++i; if (i == args.end()) { - this->SetError("DOWNLOAD missing VAR for LOG."); + status.SetError("DOWNLOAD missing VAR for LOG."); return false; } logVar = *i; } else if (*i == "STATUS") { ++i; if (i == args.end()) { - this->SetError("DOWNLOAD missing VAR for STATUS."); + status.SetError("DOWNLOAD missing VAR for STATUS."); return false; } statusVar = *i; } else if (*i == "TLS_VERIFY") { ++i; if (i != args.end()) { - tls_verify = cmSystemTools::IsOn(*i); + tls_verify = cmIsOn(*i); } else { - this->SetError("TLS_VERIFY missing bool value."); + status.SetError("TLS_VERIFY missing bool value."); return false; } } else if (*i == "TLS_CAINFO") { @@ -1702,7 +1658,7 @@ bool cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args) if (i != args.end()) { cainfo = i->c_str(); } else { - this->SetError("TLS_CAFILE missing file value."); + status.SetError("TLS_CAFILE missing file value."); return false; } } else if (*i == "NETRC_FILE") { @@ -1710,7 +1666,7 @@ bool cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args) if (i != args.end()) { netrc_file = *i; } else { - this->SetError("DOWNLOAD missing file value for NETRC_FILE."); + status.SetError("DOWNLOAD missing file value for NETRC_FILE."); return false; } } else if (*i == "NETRC") { @@ -1718,13 +1674,13 @@ bool cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args) if (i != args.end()) { netrc_level = *i; } else { - this->SetError("DOWNLOAD missing level value for NETRC."); + status.SetError("DOWNLOAD missing level value for NETRC."); return false; } } else if (*i == "EXPECTED_MD5") { ++i; if (i == args.end()) { - this->SetError("DOWNLOAD missing sum value for EXPECTED_MD5."); + status.SetError("DOWNLOAD missing sum value for EXPECTED_MD5."); return false; } hash = cm::make_unique<cmCryptoHash>(cmCryptoHash::AlgoMD5); @@ -1735,46 +1691,44 @@ bool cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args) } else if (*i == "EXPECTED_HASH") { ++i; if (i == args.end()) { - this->SetError("DOWNLOAD missing ALGO=value for EXPECTED_HASH."); + status.SetError("DOWNLOAD missing ALGO=value for EXPECTED_HASH."); return false; } 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; - this->SetError(err); + cmStrCat("DOWNLOAD EXPECTED_HASH expects ALGO=value but got: ", *i); + status.SetError(err); return false; } std::string algo = i->substr(0, pos); expectedHash = cmSystemTools::LowerCase(i->substr(pos + 1)); - hash = std::unique_ptr<cmCryptoHash>(cmCryptoHash::New(algo.c_str())); + hash = std::unique_ptr<cmCryptoHash>(cmCryptoHash::New(algo)); if (!hash) { - std::string err = "DOWNLOAD EXPECTED_HASH given unknown ALGO: "; - err += algo; - this->SetError(err); + std::string err = + cmStrCat("DOWNLOAD EXPECTED_HASH given unknown ALGO: ", algo); + status.SetError(err); return false; } hashMatchMSG = algo + " hash"; } else if (*i == "USERPWD") { ++i; if (i == args.end()) { - this->SetError("DOWNLOAD missing string for USERPWD."); + status.SetError("DOWNLOAD missing string for USERPWD."); return false; } userpwd = *i; } else if (*i == "HTTPHEADER") { ++i; if (i == args.end()) { - this->SetError("DOWNLOAD missing string for HTTPHEADER."); + status.SetError("DOWNLOAD missing string for HTTPHEADER."); return false; } curl_headers.push_back(*i); } else { // Do not return error for compatibility reason. - std::string err = "Unexpected argument: "; - err += *i; - this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, err); + std::string err = cmStrCat("Unexpected argument: ", *i); + status.GetMakefile().IssueMessage(MessageType::AUTHOR_WARNING, err); } ++i; } @@ -1786,13 +1740,12 @@ bool cmFileCommand::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; - this->Makefile->AddDefinition(statusVar, result.str().c_str()); + status.GetMakefile().AddDefinition(statusVar, result.str()); } return true; } @@ -1805,13 +1758,13 @@ bool cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args) std::string errstring = "DOWNLOAD error: cannot create directory '" + dir + "' - Specify file by full path name and verify that you " "have directory creation and file write privileges."; - this->SetError(errstring); + status.SetError(errstring); return false; } cmsys::ofstream fout(file.c_str(), std::ios::binary); if (!fout) { - this->SetError("DOWNLOAD cannot open file for write."); + status.SetError("DOWNLOAD cannot open file for write."); return false; } @@ -1823,7 +1776,7 @@ bool cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args) ::curl_global_init(CURL_GLOBAL_DEFAULT); curl = ::curl_easy_init(); if (!curl) { - this->SetError("DOWNLOAD error initializing curl."); + status.SetError("DOWNLOAD error initializing curl."); return false; } @@ -1857,7 +1810,7 @@ bool cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args) // command arg comes first std::string const& cainfo_err = cmCurlSetCAInfo(curl, cainfo); if (!cainfo_err.empty()) { - this->SetError(cainfo_err); + status.SetError(cainfo_err); return false; } @@ -1867,7 +1820,7 @@ bool cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args) std::string const& netrc_option_err = cmCurlSetNETRCOption(curl, netrc_level, netrc_file); if (!netrc_option_err.empty()) { - this->SetError(netrc_option_err); + status.SetError(netrc_option_err); return false; } @@ -1903,7 +1856,7 @@ bool cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args) // scope intentionally, rather than inside the "if(showProgress)" // block... // - cURLProgressHelper helper(this, "download"); + cURLProgressHelper helper(&status.GetMakefile(), "download"); if (showProgress) { res = ::curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0); @@ -1941,7 +1894,7 @@ bool cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args) std::ostringstream result; result << static_cast<int>(res) << ";\"" << ::curl_easy_strerror(res) << "\""; - this->Makefile->AddDefinition(statusVar, result.str().c_str()); + status.GetMakefile().AddDefinition(statusVar, result.str()); } ::curl_global_cleanup(); @@ -1956,7 +1909,7 @@ bool cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args) if (hash) { std::string actualHash = hash->HashFile(file); if (actualHash.empty()) { - this->SetError("DOWNLOAD cannot compute hash on downloaded file"); + status.SetError("DOWNLOAD cannot compute hash on downloaded file"); return false; } @@ -1970,34 +1923,36 @@ bool cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args) << ::curl_easy_strerror(res) << "\"]" << std::endl; if (!statusVar.empty() && res == 0) { - std::string status = "1;HASH mismatch: " - "expected: " + - expectedHash + " actual: " + actualHash; - this->Makefile->AddDefinition(statusVar, status.c_str()); + status.GetMakefile().AddDefinition(statusVar, + "1;HASH mismatch: " + "expected: " + + expectedHash + + " actual: " + actualHash); } - this->SetError(oss.str()); + status.SetError(oss.str()); return false; } } if (!logVar.empty()) { chunkDebug.push_back(0); - this->Makefile->AddDefinition(logVar, chunkDebug.data()); + status.GetMakefile().AddDefinition(logVar, chunkDebug.data()); } return true; #else - this->SetError("DOWNLOAD not supported by bootstrap cmake."); + status.SetError("DOWNLOAD not supported by bootstrap cmake."); return false; #endif } -bool cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args) +bool HandleUploadCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { -#if defined(CMAKE_BUILD_WITH_CMAKE) +#if !defined(CMAKE_BOOTSTRAP) if (args.size() < 3) { - this->SetError("UPLOAD must be called with at least three arguments."); + status.SetError("UPLOAD must be called with at least three arguments."); return false; } std::vector<std::string>::const_iterator i = args.begin(); @@ -2013,9 +1968,10 @@ bool cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args) std::string statusVar; bool showProgress = false; std::string userpwd; - std::string netrc_level = this->Makefile->GetSafeDefinition("CMAKE_NETRC"); + std::string netrc_level = + status.GetMakefile().GetSafeDefinition("CMAKE_NETRC"); std::string netrc_file = - this->Makefile->GetSafeDefinition("CMAKE_NETRC_FILE"); + status.GetMakefile().GetSafeDefinition("CMAKE_NETRC_FILE"); std::vector<std::string> curl_headers; @@ -2025,7 +1981,7 @@ bool cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args) if (i != args.end()) { timeout = atol(i->c_str()); } else { - this->SetError("UPLOAD missing time for TIMEOUT."); + status.SetError("UPLOAD missing time for TIMEOUT."); return false; } } else if (*i == "INACTIVITY_TIMEOUT") { @@ -2033,20 +1989,20 @@ bool cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args) if (i != args.end()) { inactivity_timeout = atol(i->c_str()); } else { - this->SetError("UPLOAD missing time for INACTIVITY_TIMEOUT."); + status.SetError("UPLOAD missing time for INACTIVITY_TIMEOUT."); return false; } } else if (*i == "LOG") { ++i; if (i == args.end()) { - this->SetError("UPLOAD missing VAR for LOG."); + status.SetError("UPLOAD missing VAR for LOG."); return false; } logVar = *i; } else if (*i == "STATUS") { ++i; if (i == args.end()) { - this->SetError("UPLOAD missing VAR for STATUS."); + status.SetError("UPLOAD missing VAR for STATUS."); return false; } statusVar = *i; @@ -2057,7 +2013,7 @@ bool cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args) if (i != args.end()) { netrc_file = *i; } else { - this->SetError("UPLOAD missing file value for NETRC_FILE."); + status.SetError("UPLOAD missing file value for NETRC_FILE."); return false; } } else if (*i == "NETRC") { @@ -2065,28 +2021,27 @@ bool cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args) if (i != args.end()) { netrc_level = *i; } else { - this->SetError("UPLOAD missing level value for NETRC."); + status.SetError("UPLOAD missing level value for NETRC."); return false; } } else if (*i == "USERPWD") { ++i; if (i == args.end()) { - this->SetError("UPLOAD missing string for USERPWD."); + status.SetError("UPLOAD missing string for USERPWD."); return false; } userpwd = *i; } else if (*i == "HTTPHEADER") { ++i; if (i == args.end()) { - this->SetError("UPLOAD missing string for HTTPHEADER."); + status.SetError("UPLOAD missing string for HTTPHEADER."); return false; } curl_headers.push_back(*i); } else { // Do not return error for compatibility reason. - std::string err = "Unexpected argument: "; - err += *i; - this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, err); + std::string err = cmStrCat("Unexpected argument: ", *i); + status.GetMakefile().IssueMessage(MessageType::AUTHOR_WARNING, err); } ++i; @@ -2096,9 +2051,9 @@ bool cmFileCommand::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."; - this->SetError(errStr); + std::string errStr = + cmStrCat("UPLOAD cannot open file '", filename, "' for reading."); + status.SetError(errStr); return false; } @@ -2112,7 +2067,7 @@ bool cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args) ::curl_global_init(CURL_GLOBAL_DEFAULT); curl = ::curl_easy_init(); if (!curl) { - this->SetError("UPLOAD error initializing curl."); + status.SetError("UPLOAD error initializing curl."); fclose(fin); return false; } @@ -2171,7 +2126,7 @@ bool cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args) // scope intentionally, rather than inside the "if(showProgress)" // block... // - cURLProgressHelper helper(this, "upload"); + cURLProgressHelper helper(&status.GetMakefile(), "upload"); if (showProgress) { res = ::curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0); @@ -2206,7 +2161,7 @@ bool cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args) std::string const& netrc_option_err = cmCurlSetNETRCOption(curl, netrc_level, netrc_file); if (!netrc_option_err.empty()) { - this->SetError(netrc_option_err); + status.SetError(netrc_option_err); return false; } @@ -2228,7 +2183,7 @@ bool cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args) std::ostringstream result; result << static_cast<int>(res) << ";\"" << ::curl_easy_strerror(res) << "\""; - this->Makefile->AddDefinition(statusVar, result.str().c_str()); + status.GetMakefile().AddDefinition(statusVar, result.str()); } ::curl_global_cleanup(); @@ -2253,22 +2208,22 @@ bool cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args) log += "\n"; } - this->Makefile->AddDefinition(logVar, log.c_str()); + status.GetMakefile().AddDefinition(logVar, log); } return true; #else - this->SetError("UPLOAD not supported by bootstrap cmake."); + status.SetError("UPLOAD not supported by bootstrap cmake."); return false; #endif } -void cmFileCommand::AddEvaluationFile(const std::string& inputName, - const std::string& outputExpr, - const std::string& condition, - bool inputIsContent) +void AddEvaluationFile(const std::string& inputName, + const std::string& outputExpr, + const std::string& condition, bool inputIsContent, + cmExecutionStatus& status) { - cmListFileBacktrace lfbt = this->Makefile->GetBacktrace(); + cmListFileBacktrace lfbt = status.GetMakefile().GetBacktrace(); cmGeneratorExpression outputGe(lfbt); std::unique_ptr<cmCompiledGeneratorExpression> outputCge = @@ -2278,52 +2233,54 @@ void cmFileCommand::AddEvaluationFile(const std::string& inputName, std::unique_ptr<cmCompiledGeneratorExpression> conditionCge = conditionGe.Parse(condition); - this->Makefile->AddEvaluationFile(inputName, std::move(outputCge), - std::move(conditionCge), inputIsContent); + status.GetMakefile().AddEvaluationFile( + inputName, std::move(outputCge), std::move(conditionCge), inputIsContent); } -bool cmFileCommand::HandleGenerateCommand(std::vector<std::string> const& args) +bool HandleGenerateCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.size() < 5) { - this->SetError("Incorrect arguments to GENERATE subcommand."); + status.SetError("Incorrect arguments to GENERATE subcommand."); return false; } if (args[1] != "OUTPUT") { - this->SetError("Incorrect arguments to GENERATE subcommand."); + status.SetError("Incorrect arguments to GENERATE subcommand."); return false; } std::string condition; if (args.size() > 5) { if (args[5] != "CONDITION") { - this->SetError("Incorrect arguments to GENERATE subcommand."); + status.SetError("Incorrect arguments to GENERATE subcommand."); return false; } if (args.size() != 7) { - this->SetError("Incorrect arguments to GENERATE subcommand."); + status.SetError("Incorrect arguments to GENERATE subcommand."); return false; } condition = args[6]; if (condition.empty()) { - this->SetError("CONDITION of sub-command GENERATE must not be empty if " - "specified."); + status.SetError("CONDITION of sub-command GENERATE must not be empty if " + "specified."); return false; } } std::string output = args[2]; const bool inputIsContent = args[3] != "INPUT"; if (inputIsContent && args[3] != "CONTENT") { - this->SetError("Incorrect arguments to GENERATE subcommand."); + status.SetError("Incorrect arguments to GENERATE subcommand."); return false; } std::string input = args[4]; - this->AddEvaluationFile(input, output, condition, inputIsContent); + AddEvaluationFile(input, output, condition, inputIsContent, status); return true; } -bool cmFileCommand::HandleLockCommand(std::vector<std::string> const& args) +bool HandleLockCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { -#if defined(CMAKE_BUILD_WITH_CMAKE) +#if !defined(CMAKE_BOOTSTRAP) // Default values bool directory = false; bool release = false; @@ -2339,7 +2296,7 @@ bool cmFileCommand::HandleLockCommand(std::vector<std::string> const& args) // Parse arguments if (args.size() < 2) { - this->Makefile->IssueMessage( + status.GetMakefile().IssueMessage( MessageType::FATAL_ERROR, "sub-command LOCK requires at least two arguments."); return false; @@ -2355,7 +2312,7 @@ bool cmFileCommand::HandleLockCommand(std::vector<std::string> const& args) ++i; const char* merr = "expected FUNCTION, FILE or PROCESS after GUARD"; if (i >= args.size()) { - this->Makefile->IssueMessage(MessageType::FATAL_ERROR, merr); + status.GetMakefile().IssueMessage(MessageType::FATAL_ERROR, merr); return false; } if (args[i] == "FUNCTION") { @@ -2367,14 +2324,14 @@ bool cmFileCommand::HandleLockCommand(std::vector<std::string> const& args) } else { std::ostringstream e; e << merr << ", but got:\n \"" << args[i] << "\"."; - this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str()); + status.GetMakefile().IssueMessage(MessageType::FATAL_ERROR, e.str()); return false; } } else if (args[i] == "RESULT_VARIABLE") { ++i; if (i >= args.size()) { - this->Makefile->IssueMessage( + status.GetMakefile().IssueMessage( MessageType::FATAL_ERROR, "expected variable name after RESULT_VARIABLE"); return false; @@ -2383,16 +2340,15 @@ bool cmFileCommand::HandleLockCommand(std::vector<std::string> const& args) } else if (args[i] == "TIMEOUT") { ++i; if (i >= args.size()) { - this->Makefile->IssueMessage(MessageType::FATAL_ERROR, - "expected timeout value after TIMEOUT"); + status.GetMakefile().IssueMessage( + MessageType::FATAL_ERROR, "expected timeout value after TIMEOUT"); return false; } long scanned; - if (!cmSystemTools::StringToLong(args[i].c_str(), &scanned) || - scanned < 0) { + if (!cmStrToLong(args[i], &scanned) || scanned < 0) { std::ostringstream e; e << "TIMEOUT value \"" << args[i] << "\" is not an unsigned integer."; - this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str()); + status.GetMakefile().IssueMessage(MessageType::FATAL_ERROR, e.str()); return false; } timeout = static_cast<unsigned long>(scanned); @@ -2400,7 +2356,7 @@ bool cmFileCommand::HandleLockCommand(std::vector<std::string> const& args) std::ostringstream e; e << "expected DIRECTORY, RELEASE, GUARD, RESULT_VARIABLE or TIMEOUT\n"; e << "but got: \"" << args[i] << "\"."; - this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str()); + status.GetMakefile().IssueMessage(MessageType::FATAL_ERROR, e.str()); return false; } } @@ -2410,7 +2366,7 @@ bool cmFileCommand::HandleLockCommand(std::vector<std::string> const& args) } if (!cmsys::SystemTools::FileIsFullPath(path)) { - path = this->Makefile->GetCurrentSourceDirectory() + "/" + path; + path = status.GetMakefile().GetCurrentSourceDirectory() + "/" + path; } // Unify path (remove '//', '/../', ...) @@ -2422,7 +2378,7 @@ bool cmFileCommand::HandleLockCommand(std::vector<std::string> const& args) std::ostringstream e; e << "directory\n \"" << parentDir << "\"\ncreation failed "; e << "(check permissions)."; - this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str()); + status.GetMakefile().IssueMessage(MessageType::FATAL_ERROR, e.str()); cmSystemTools::SetFatalErrorOccured(); return false; } @@ -2430,7 +2386,7 @@ bool cmFileCommand::HandleLockCommand(std::vector<std::string> const& args) if (!file) { std::ostringstream e; e << "file\n \"" << path << "\"\ncreation failed (check permissions)."; - this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str()); + status.GetMakefile().IssueMessage(MessageType::FATAL_ERROR, e.str()); cmSystemTools::SetFatalErrorOccured(); return false; } @@ -2438,7 +2394,7 @@ bool cmFileCommand::HandleLockCommand(std::vector<std::string> const& args) // Actual lock/unlock cmFileLockPool& lockPool = - this->Makefile->GetGlobalGenerator()->GetFileLockPool(); + status.GetMakefile().GetGlobalGenerator()->GetFileLockPool(); cmFileLockResult fileLockResult(cmFileLockResult::MakeOk()); if (release) { @@ -2465,32 +2421,32 @@ bool cmFileCommand::HandleLockCommand(std::vector<std::string> const& args) if (resultVariable.empty() && !fileLockResult.IsOk()) { std::ostringstream e; e << "error locking file\n \"" << path << "\"\n" << result << "."; - this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str()); + status.GetMakefile().IssueMessage(MessageType::FATAL_ERROR, e.str()); cmSystemTools::SetFatalErrorOccured(); return false; } if (!resultVariable.empty()) { - this->Makefile->AddDefinition(resultVariable, result.c_str()); + status.GetMakefile().AddDefinition(resultVariable, result); } return true; #else static_cast<void>(args); - this->SetError("sub-command LOCK not implemented in bootstrap cmake"); + status.SetError("sub-command LOCK not implemented in bootstrap cmake"); return false; #endif } -bool cmFileCommand::HandleTimestampCommand( - std::vector<std::string> const& args) +bool HandleTimestampCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.size() < 3) { - this->SetError("sub-command TIMESTAMP requires at least two arguments."); + status.SetError("sub-command TIMESTAMP requires at least two arguments."); return false; } if (args.size() > 5) { - this->SetError("sub-command TIMESTAMP takes at most four arguments."); + status.SetError("sub-command TIMESTAMP takes at most four arguments."); return false; } @@ -2512,7 +2468,7 @@ bool cmFileCommand::HandleTimestampCommand( } else { std::string e = " TIMESTAMP sub-command does not recognize option " + args[argsIndex] + "."; - this->SetError(e); + status.SetError(e); return false; } } @@ -2520,17 +2476,18 @@ bool cmFileCommand::HandleTimestampCommand( cmTimestamp timestamp; std::string result = timestamp.FileModificationTime(filename.c_str(), formatString, utcFlag); - this->Makefile->AddDefinition(outputVariable, result.c_str()); + status.GetMakefile().AddDefinition(outputVariable, result); return true; } -bool cmFileCommand::HandleSizeCommand(std::vector<std::string> const& args) +bool HandleSizeCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.size() != 3) { std::ostringstream e; e << args[0] << " requires a file name and output variable"; - this->SetError(e.str()); + status.SetError(e.str()); return false; } @@ -2543,24 +2500,23 @@ bool cmFileCommand::HandleSizeCommand(std::vector<std::string> const& args) if (!cmSystemTools::FileExists(filename, true)) { std::ostringstream e; e << "SIZE requested of path that is not readable:\n " << filename; - this->SetError(e.str()); + status.SetError(e.str()); return false; } - this->Makefile->AddDefinition( - outputVariable, - std::to_string(cmSystemTools::FileLength(filename)).c_str()); + status.GetMakefile().AddDefinition( + outputVariable, std::to_string(cmSystemTools::FileLength(filename))); return true; } -bool cmFileCommand::HandleReadSymlinkCommand( - std::vector<std::string> const& args) +bool HandleReadSymlinkCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.size() != 3) { std::ostringstream e; e << args[0] << " requires a file name and output variable"; - this->SetError(e.str()); + status.SetError(e.str()); return false; } @@ -2572,21 +2528,21 @@ bool cmFileCommand::HandleReadSymlinkCommand( std::ostringstream e; e << "READ_SYMLINK requested of path that is not a symlink:\n " << filename; - this->SetError(e.str()); + status.SetError(e.str()); return false; } - this->Makefile->AddDefinition(outputVariable, result.c_str()); + status.GetMakefile().AddDefinition(outputVariable, result); return true; } -bool cmFileCommand::HandleCreateLinkCommand( - std::vector<std::string> const& args) +bool HandleCreateLinkCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.size() < 3) { - this->SetError("CREATE_LINK must be called with at least two additional " - "arguments"); + status.SetError("CREATE_LINK must be called with at least two additional " + "arguments"); return false; } @@ -2611,7 +2567,7 @@ bool cmFileCommand::HandleCreateLinkCommand( parser.Parse(cmMakeRange(args).advance(3), &unconsumedArgs); if (!unconsumedArgs.empty()) { - this->SetError("unknown argument: \"" + unconsumedArgs.front() + '\"'); + status.SetError("unknown argument: \"" + unconsumedArgs.front() + '\"'); return false; } @@ -2622,10 +2578,10 @@ bool cmFileCommand::HandleCreateLinkCommand( if (fileName == newFileName) { result = "CREATE_LINK cannot use same file and newfile"; if (!arguments.Result.empty()) { - this->Makefile->AddDefinition(arguments.Result, result.c_str()); + status.GetMakefile().AddDefinition(arguments.Result, result); return true; } - this->SetError(result); + status.SetError(result); return false; } @@ -2633,10 +2589,10 @@ bool cmFileCommand::HandleCreateLinkCommand( if (!arguments.Symbolic && !cmSystemTools::FileExists(fileName)) { result = "Cannot hard link \'" + fileName + "\' as it does not exist."; if (!arguments.Result.empty()) { - this->Makefile->AddDefinition(arguments.Result, result.c_str()); + status.GetMakefile().AddDefinition(arguments.Result, result); return true; } - this->SetError(result); + status.SetError(result); return false; } @@ -2650,10 +2606,10 @@ bool cmFileCommand::HandleCreateLinkCommand( << cmSystemTools::GetLastSystemError() << "\n"; if (!arguments.Result.empty()) { - this->Makefile->AddDefinition(arguments.Result, e.str().c_str()); + status.GetMakefile().AddDefinition(arguments.Result, e.str()); return true; } - this->SetError(e.str()); + status.SetError(e.str()); return false; } @@ -2680,13 +2636,242 @@ bool cmFileCommand::HandleCreateLinkCommand( result = "0"; } else if (arguments.Result.empty()) { // The operation failed and the result is not reported in a variable. - this->SetError(result); + status.SetError(result); return false; } if (!arguments.Result.empty()) { - this->Makefile->AddDefinition(arguments.Result, result.c_str()); + status.GetMakefile().AddDefinition(arguments.Result, result); + } + + return true; +} + +bool HandleGetRuntimeDependenciesCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) +{ + static const std::set<std::string> supportedPlatforms = { "Windows", "Linux", + "Darwin" }; + std::string platform = + status.GetMakefile().GetSafeDefinition("CMAKE_HOST_SYSTEM_NAME"); + if (!supportedPlatforms.count(platform)) { + std::ostringstream e; + e << "GET_RUNTIME_DEPENDENCIES is not supported on system \"" << platform + << "\""; + status.SetError(e.str()); + cmSystemTools::SetFatalErrorOccured(); + return false; + } + + if (status.GetMakefile().GetState()->GetMode() == cmState::Project) { + status.GetMakefile().IssueMessage( + MessageType::AUTHOR_WARNING, + "You have used file(GET_RUNTIME_DEPENDENCIES)" + " in project mode. This is probably not what " + "you intended to do. Instead, please consider" + " using it in an install(CODE) or " + "install(SCRIPT) command. For example:" + "\n install(CODE [[" + "\n file(GET_RUNTIME_DEPENDENCIES" + "\n # ..." + "\n )" + "\n ]])"); + } + + struct Arguments + { + std::string ResolvedDependenciesVar; + std::string UnresolvedDependenciesVar; + std::string ConflictingDependenciesPrefix; + std::string BundleExecutable; + std::vector<std::string> Executables; + std::vector<std::string> Libraries; + std::vector<std::string> Directories; + std::vector<std::string> Modules; + std::vector<std::string> PreIncludeRegexes; + std::vector<std::string> PreExcludeRegexes; + std::vector<std::string> PostIncludeRegexes; + std::vector<std::string> PostExcludeRegexes; + }; + + static auto const parser = + cmArgumentParser<Arguments>{} + .Bind("RESOLVED_DEPENDENCIES_VAR"_s, &Arguments::ResolvedDependenciesVar) + .Bind("UNRESOLVED_DEPENDENCIES_VAR"_s, + &Arguments::UnresolvedDependenciesVar) + .Bind("CONFLICTING_DEPENDENCIES_PREFIX"_s, + &Arguments::ConflictingDependenciesPrefix) + .Bind("BUNDLE_EXECUTABLE"_s, &Arguments::BundleExecutable) + .Bind("EXECUTABLES"_s, &Arguments::Executables) + .Bind("LIBRARIES"_s, &Arguments::Libraries) + .Bind("MODULES"_s, &Arguments::Modules) + .Bind("DIRECTORIES"_s, &Arguments::Directories) + .Bind("PRE_INCLUDE_REGEXES"_s, &Arguments::PreIncludeRegexes) + .Bind("PRE_EXCLUDE_REGEXES"_s, &Arguments::PreExcludeRegexes) + .Bind("POST_INCLUDE_REGEXES"_s, &Arguments::PostIncludeRegexes) + .Bind("POST_EXCLUDE_REGEXES"_s, &Arguments::PostExcludeRegexes); + + std::vector<std::string> unrecognizedArguments; + std::vector<std::string> keywordsMissingValues; + auto parsedArgs = + parser.Parse(cmMakeRange(args).advance(1), &unrecognizedArguments, + &keywordsMissingValues); + auto argIt = unrecognizedArguments.begin(); + if (argIt != unrecognizedArguments.end()) { + std::ostringstream e; + e << "Unrecognized argument: \"" << *argIt << "\""; + status.SetError(e.str()); + cmSystemTools::SetFatalErrorOccured(); + return false; + } + argIt = keywordsMissingValues.begin(); + if (argIt != keywordsMissingValues.end()) { + std::ostringstream e; + e << "Keyword missing value: " << *argIt; + status.SetError(e.str()); + cmSystemTools::SetFatalErrorOccured(); + return false; + } + + cmRuntimeDependencyArchive archive( + status, parsedArgs.Directories, parsedArgs.BundleExecutable, + parsedArgs.PreIncludeRegexes, parsedArgs.PreExcludeRegexes, + parsedArgs.PostIncludeRegexes, parsedArgs.PostExcludeRegexes); + if (!archive.Prepare()) { + cmSystemTools::SetFatalErrorOccured(); + return false; + } + + if (!archive.GetRuntimeDependencies( + parsedArgs.Executables, parsedArgs.Libraries, parsedArgs.Modules)) { + cmSystemTools::SetFatalErrorOccured(); + return false; } + 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(); + assert(it != val.second.end()); + auto const& firstPath = *it; + while (++it != val.second.end()) { + if (!cmSystemTools::SameFile(firstPath, *it)) { + unique = false; + break; + } + } + + if (unique) { + deps.push_back(firstPath); + } else if (!parsedArgs.ConflictingDependenciesPrefix.empty()) { + conflictingDeps.push_back(val.first); + std::vector<std::string> paths; + paths.insert(paths.begin(), val.second.begin(), val.second.end()); + std::string varName = + parsedArgs.ConflictingDependenciesPrefix + "_" + val.first; + std::string pathsStr = cmJoin(paths, ";"); + status.GetMakefile().AddDefinition(varName, pathsStr); + } else { + std::ostringstream e; + e << "Multiple conflicting paths found for " << val.first << ":"; + for (auto const& path : val.second) { + e << "\n " << path; + } + status.SetError(e.str()); + cmSystemTools::SetFatalErrorOccured(); + return false; + } + } + if (!archive.GetUnresolvedPaths().empty()) { + if (!parsedArgs.UnresolvedDependenciesVar.empty()) { + unresolvedDeps.insert(unresolvedDeps.begin(), + archive.GetUnresolvedPaths().begin(), + archive.GetUnresolvedPaths().end()); + } else { + auto it = archive.GetUnresolvedPaths().begin(); + assert(it != archive.GetUnresolvedPaths().end()); + std::ostringstream e; + e << "Could not resolve file " << *it; + status.SetError(e.str()); + cmSystemTools::SetFatalErrorOccured(); + return false; + } + } + + if (!parsedArgs.ResolvedDependenciesVar.empty()) { + std::string val = cmJoin(deps, ";"); + status.GetMakefile().AddDefinition(parsedArgs.ResolvedDependenciesVar, + val); + } + if (!parsedArgs.UnresolvedDependenciesVar.empty()) { + std::string val = cmJoin(unresolvedDeps, ";"); + status.GetMakefile().AddDefinition(parsedArgs.UnresolvedDependenciesVar, + val); + } + if (!parsedArgs.ConflictingDependenciesPrefix.empty()) { + std::string val = cmJoin(conflictingDeps, ";"); + status.GetMakefile().AddDefinition( + parsedArgs.ConflictingDependenciesPrefix + "_FILENAMES", val); + } return true; } + +} // namespace + +bool cmFileCommand(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{ + { "WRITE"_s, HandleWriteCommand }, + { "APPEND"_s, HandleAppendCommand }, + { "DOWNLOAD"_s, HandleDownloadCommand }, + { "UPLOAD"_s, HandleUploadCommand }, + { "READ"_s, HandleReadCommand }, + { "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 }, + { "STRINGS"_s, HandleStringsCommand }, + { "GLOB"_s, HandleGlobCommand }, + { "GLOB_RECURSE"_s, HandleGlobRecurseCommand }, + { "MAKE_DIRECTORY"_s, HandleMakeDirectoryCommand }, + { "RENAME"_s, HandleRename }, + { "REMOVE"_s, HandleRemove }, + { "REMOVE_RECURSE"_s, HandleRemoveRecurse }, + { "COPY"_s, HandleCopyCommand }, + { "INSTALL"_s, HandleInstallCommand }, + { "DIFFERENT"_s, HandleDifferentCommand }, + { "RPATH_CHANGE"_s, HandleRPathChangeCommand }, + { "CHRPATH"_s, HandleRPathChangeCommand }, + { "RPATH_CHECK"_s, HandleRPathCheckCommand }, + { "RPATH_REMOVE"_s, HandleRPathRemoveCommand }, + { "READ_ELF"_s, HandleReadElfCommand }, + { "RELATIVE_PATH"_s, HandleRelativePathCommand }, + { "TO_CMAKE_PATH"_s, HandleCMakePathCommand }, + { "TO_NATIVE_PATH"_s, HandleNativePathCommand }, + { "TOUCH"_s, HandleTouchCommand }, + { "TOUCH_NOCREATE"_s, HandleTouchNocreateCommand }, + { "TIMESTAMP"_s, HandleTimestampCommand }, + { "GENERATE"_s, HandleGenerateCommand }, + { "LOCK"_s, HandleLockCommand }, + { "SIZE"_s, HandleSizeCommand }, + { "READ_SYMLINK"_s, HandleReadSymlinkCommand }, + { "CREATE_LINK"_s, HandleCreateLinkCommand }, + { "GET_RUNTIME_DEPENDENCIES"_s, HandleGetRuntimeDependenciesCommand }, + }; + + return subcommand(args[0], args, status); +} diff --git a/Source/cmFileCommand.h b/Source/cmFileCommand.h index 12c5115..8c9b219 100644 --- a/Source/cmFileCommand.h +++ b/Source/cmFileCommand.h @@ -8,65 +8,9 @@ #include <string> #include <vector> -#include "cmCommand.h" - class cmExecutionStatus; -/** \class cmFileCommand - * \brief Command for manipulation of files - * - */ -class cmFileCommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - cmCommand* Clone() override { return new cmFileCommand; } - - /** - * 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 HandleRename(std::vector<std::string> const& args); - bool HandleRemove(std::vector<std::string> const& args, bool recurse); - bool HandleWriteCommand(std::vector<std::string> const& args, bool append); - bool HandleReadCommand(std::vector<std::string> const& args); - bool HandleHashCommand(std::vector<std::string> const& args); - bool HandleStringsCommand(std::vector<std::string> const& args); - bool HandleGlobCommand(std::vector<std::string> const& args, bool recurse); - bool HandleTouchCommand(std::vector<std::string> const& args, bool create); - bool HandleMakeDirectoryCommand(std::vector<std::string> const& args); - - bool HandleRelativePathCommand(std::vector<std::string> const& args); - bool HandleCMakePathCommand(std::vector<std::string> const& args, - bool nativePath); - bool HandleReadElfCommand(std::vector<std::string> const& args); - bool HandleRPathChangeCommand(std::vector<std::string> const& args); - bool HandleRPathCheckCommand(std::vector<std::string> const& args); - bool HandleRPathRemoveCommand(std::vector<std::string> const& args); - bool HandleDifferentCommand(std::vector<std::string> const& args); - - bool HandleCopyCommand(std::vector<std::string> const& args); - bool HandleInstallCommand(std::vector<std::string> const& args); - bool HandleDownloadCommand(std::vector<std::string> const& args); - bool HandleUploadCommand(std::vector<std::string> const& args); - - bool HandleTimestampCommand(std::vector<std::string> const& args); - bool HandleGenerateCommand(std::vector<std::string> const& args); - bool HandleLockCommand(std::vector<std::string> const& args); - bool HandleSizeCommand(std::vector<std::string> const& args); - bool HandleReadSymlinkCommand(std::vector<std::string> const& args); - bool HandleCreateLinkCommand(std::vector<std::string> const& args); - -private: - void AddEvaluationFile(const std::string& inputName, - const std::string& outputExpr, - const std::string& condition, bool inputIsContent); -}; +bool cmFileCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmFileCopier.cxx b/Source/cmFileCopier.cxx index 49e8cd5..e00e726 100644 --- a/Source/cmFileCopier.cxx +++ b/Source/cmFileCopier.cxx @@ -3,10 +3,11 @@ #include "cmFileCopier.h" +#include "cmExecutionStatus.h" #include "cmFSPermissions.h" -#include "cmFileCommand.h" #include "cmFileTimes.h" #include "cmMakefile.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmsys/Directory.hxx" #include "cmsys/Glob.hxx" @@ -20,9 +21,9 @@ using namespace cmFSPermissions; -cmFileCopier::cmFileCopier(cmFileCommand* command, const char* name) - : FileCommand(command) - , Makefile(command->GetMakefile()) +cmFileCopier::cmFileCopier(cmExecutionStatus& status, const char* name) + : Status(status) + , Makefile(&status.GetMakefile()) , Name(name) , Always(false) , MatchlessFiles(true) @@ -90,8 +91,9 @@ bool cmFileCopier::SetPermissions(const std::string& toFile, if (!cmSystemTools::SetPermissions(toFile, permissions)) { std::ostringstream e; - e << this->Name << " cannot set permissions on \"" << toFile << "\""; - this->FileCommand->SetError(e.str()); + e << this->Name << " cannot set permissions on \"" << toFile + << "\": " << cmSystemTools::GetLastSystemError() << "."; + this->Status.SetError(e.str()); return false; } } @@ -105,7 +107,7 @@ bool cmFileCopier::CheckPermissions(std::string const& arg, if (!cmFSPermissions::stringToModeT(arg, permissions)) { std::ostringstream e; e << this->Name << " given invalid permission \"" << arg << "\"."; - this->FileCommand->SetError(e.str()); + this->Status.SetError(e.str()); return false; } return true; @@ -120,8 +122,9 @@ 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 << "\"."; - this->FileCommand->SetError(e.str()); + e << this->Name << " cannot find \"" << fromFile + << "\": " << cmSystemTools::GetLastSystemError() << "."; + this->Status.SetError(e.str()); return false; } @@ -129,7 +132,7 @@ void cmFileCopier::NotBeforeMatch(std::string const& arg) { std::ostringstream e; e << "option " << arg << " may not appear before PATTERN or REGEX."; - this->FileCommand->SetError(e.str()); + this->Status.SetError(e.str()); this->Doing = DoingError; } @@ -137,7 +140,7 @@ void cmFileCopier::NotAfterMatch(std::string const& arg) { std::ostringstream e; e << "option " << arg << " may not appear after PATTERN or REGEX."; - this->FileCommand->SetError(e.str()); + this->Status.SetError(e.str()); this->Doing = DoingError; } @@ -170,15 +173,12 @@ 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; - cmSystemTools::ExpandListArgument(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)) { - std::ostringstream e; - e << this->FileCommand->GetError() - << " Set with CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS " - "variable."; - this->FileCommand->SetError(e.str()); + this->Status.SetError( + " Set with CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS variable."); return false; } } @@ -197,7 +197,7 @@ bool cmFileCopier::Parse(std::vector<std::string> const& args) if (!this->CheckKeyword(args[i]) && !this->CheckValue(args[i])) { std::ostringstream e; e << "called with unknown argument \"" << args[i] << "\"."; - this->FileCommand->SetError(e.str()); + this->Status.SetError(e.str()); return false; } @@ -211,7 +211,7 @@ bool cmFileCopier::Parse(std::vector<std::string> const& args) if (this->Destination.empty()) { std::ostringstream e; e << this->Name << " given no DESTINATION"; - this->FileCommand->SetError(e.str()); + this->Status.SetError(e.str()); return false; } @@ -314,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; @@ -323,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; @@ -334,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()) { @@ -344,7 +343,7 @@ bool cmFileCopier::CheckValue(std::string const& arg) } else { std::ostringstream e; e << "could not compile PATTERN \"" << arg << "\"."; - this->FileCommand->SetError(e.str()); + this->Status.SetError(e.str()); this->Doing = DoingError; } } break; @@ -356,7 +355,7 @@ bool cmFileCopier::CheckValue(std::string const& arg) } else { std::ostringstream e; e << "could not compile REGEX \"" << arg << "\"."; - this->FileCommand->SetError(e.str()); + this->Status.SetError(e.str()); this->Doing = DoingError; } break; @@ -399,8 +398,8 @@ bool cmFileCopier::Run(std::vector<std::string> const& args) file += "/"; file += f; } else if (!this->FilesFromDir.empty()) { - this->FileCommand->SetError("option FILES_FROM_DIR requires all files " - "to be specified as relative paths."); + this->Status.SetError("option FILES_FROM_DIR requires all files " + "to be specified as relative paths."); return false; } else { file = f; @@ -447,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->FileCommand->SetError(e.str()); + this->Status.SetError( + "INSTALL encountered an empty string input file name."); return false; } @@ -493,7 +491,7 @@ bool cmFileCopier::InstallSymlinkChain(std::string& fromFile, while (cmSystemTools::ReadSymlink(fromFile, newFromFile)) { if (!cmSystemTools::FileIsFullPath(newFromFile)) { std::string fromFilePath = cmSystemTools::GetFilenamePath(fromFile); - newFromFile = fromFilePath + "/" + newFromFile; + newFromFile = cmStrCat(fromFilePath, "/", newFromFile); } std::string symlinkTarget = cmSystemTools::GetFilenameName(newFromFile); @@ -516,14 +514,15 @@ bool cmFileCopier::InstallSymlinkChain(std::string& fromFile, if (!cmSystemTools::CreateSymlink(symlinkTarget, toFile)) { std::ostringstream e; - e << this->Name << " cannot create symlink \"" << toFile << "\"."; - this->FileCommand->SetError(e.str()); + e << this->Name << " cannot create symlink \"" << toFile + << "\": " << cmSystemTools::GetLastSystemError() << "."; + this->Status.SetError(e.str()); return false; } } fromFile = newFromFile; - toFile = toFilePath + "/" + symlinkTarget; + toFile = cmStrCat(toFilePath, "/", symlinkTarget); } return true; @@ -537,8 +536,9 @@ 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 << "\"."; - this->FileCommand->SetError(e.str()); + << "\" to duplicate at \"" << toFile + << "\": " << cmSystemTools::GetLastSystemError() << "."; + this->Status.SetError(e.str()); return false; } @@ -568,8 +568,9 @@ bool cmFileCopier::InstallSymlink(const std::string& fromFile, if (!cmSystemTools::CreateSymlink(symlinkTarget, toFile)) { std::ostringstream e; e << this->Name << " cannot duplicate symlink \"" << fromFile - << "\" at \"" << toFile << "\"."; - this->FileCommand->SetError(e.str()); + << "\" at \"" << toFile + << "\": " << cmSystemTools::GetLastSystemError() << "."; + this->Status.SetError(e.str()); return false; } } @@ -597,8 +598,8 @@ 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 << "\"."; - this->FileCommand->SetError(e.str()); + << toFile << "\": " << cmSystemTools::GetLastSystemError() << "."; + this->Status.SetError(e.str()); return false; } @@ -613,8 +614,8 @@ bool cmFileCopier::InstallFile(const std::string& fromFile, if (!cmFileTimes::Copy(fromFile, toFile)) { std::ostringstream e; e << this->Name << " cannot set modification time on \"" << toFile - << "\""; - this->FileCommand->SetError(e.str()); + << "\": " << cmSystemTools::GetLastSystemError() << "."; + this->Status.SetError(e.str()); return false; } } @@ -650,8 +651,8 @@ 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(); - this->FileCommand->SetError(e.str()); + << "\": " << cmSystemTools::GetLastSystemError() << "."; + this->Status.SetError(e.str()); return false; } @@ -696,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/cmFileCopier.h b/Source/cmFileCopier.h index a79a60b..263a365 100644 --- a/Source/cmFileCopier.h +++ b/Source/cmFileCopier.h @@ -12,19 +12,19 @@ #include <string> #include <vector> -class cmFileCommand; +class cmExecutionStatus; class cmMakefile; // File installation helper class. struct cmFileCopier { - cmFileCopier(cmFileCommand* command, const char* name = "COPY"); + cmFileCopier(cmExecutionStatus& status, const char* name = "COPY"); virtual ~cmFileCopier(); bool Run(std::vector<std::string> const& args); protected: - cmFileCommand* FileCommand; + cmExecutionStatus& Status; cmMakefile* Makefile; const char* Name; bool Always; diff --git a/Source/cmFileInstaller.cxx b/Source/cmFileInstaller.cxx index d4f76fd..a773738 100644 --- a/Source/cmFileInstaller.cxx +++ b/Source/cmFileInstaller.cxx @@ -3,9 +3,10 @@ #include "cmFileInstaller.h" +#include "cmExecutionStatus.h" #include "cmFSPermissions.h" -#include "cmFileCommand.h" #include "cmMakefile.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cm_sys_stat.h" @@ -14,8 +15,8 @@ using namespace cmFSPermissions; -cmFileInstaller::cmFileInstaller(cmFileCommand* command) - : cmFileCopier(command, "INSTALL") +cmFileInstaller::cmFileInstaller(cmExecutionStatus& status) + : cmFileCopier(status, "INSTALL") , InstallType(cmInstallType_FILES) , Optional(false) , MessageAlways(false) @@ -28,7 +29,7 @@ cmFileInstaller::cmFileInstaller(cmFileCommand* command) // Check whether to copy files always or only if they have changed. std::string install_always; if (cmSystemTools::GetEnv("CMAKE_INSTALL_ALWAYS", install_always)) { - this->Always = cmSystemTools::IsOn(install_always); + this->Always = cmIsOn(install_always); } // Get the current manifest. this->Manifest = @@ -38,7 +39,7 @@ cmFileInstaller::~cmFileInstaller() { // Save the updated install manifest. this->Makefile->AddDefinition("CMAKE_INSTALL_MANIFEST_FILES", - this->Manifest.c_str()); + this->Manifest); } void cmFileInstaller::ManifestAppend(std::string const& file) @@ -58,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) { @@ -111,19 +112,19 @@ bool cmFileInstaller::Parse(std::vector<std::string> const& args) if (!this->Rename.empty()) { if (!this->FilesFromDir.empty()) { - this->FileCommand->SetError("INSTALL option RENAME may not be " - "combined with FILES_FROM_DIR."); + this->Status.SetError("INSTALL option RENAME may not be " + "combined with FILES_FROM_DIR."); return false; } if (this->InstallType != cmInstallType_FILES && this->InstallType != cmInstallType_PROGRAMS) { - this->FileCommand->SetError("INSTALL option RENAME may be used " - "only with FILES or PROGRAMS."); + this->Status.SetError("INSTALL option RENAME may be used " + "only with FILES or PROGRAMS."); return false; } if (this->Files.size() > 1) { - this->FileCommand->SetError("INSTALL option RENAME may be used " - "only with one file."); + this->Status.SetError("INSTALL option RENAME may be used " + "only with one file."); return false; } } @@ -134,9 +135,9 @@ bool cmFileInstaller::Parse(std::vector<std::string> const& args) if (((this->MessageAlways ? 1 : 0) + (this->MessageLazy ? 1 : 0) + (this->MessageNever ? 1 : 0)) > 1) { - this->FileCommand->SetError("INSTALL options MESSAGE_ALWAYS, " - "MESSAGE_LAZY, and MESSAGE_NEVER " - "are mutually exclusive."); + this->Status.SetError("INSTALL options MESSAGE_ALWAYS, " + "MESSAGE_LAZY, and MESSAGE_NEVER " + "are mutually exclusive."); return false; } @@ -213,7 +214,7 @@ bool cmFileInstaller::CheckKeyword(std::string const& arg) e << "INSTALL called with old-style " << arg << " argument. " << "This script was generated with an older version of CMake. " << "Re-run this cmake version on your build tree."; - this->FileCommand->SetError(e.str()); + this->Status.SetError(e.str()); this->Doing = DoingError; } else { return this->cmFileCopier::CheckKeyword(arg); @@ -257,7 +258,7 @@ bool cmFileInstaller::GetTargetTypeFromString(const std::string& stype) } else { std::ostringstream e; e << "Option TYPE given unknown value \"" << stype << "\"."; - this->FileCommand->SetError(e.str()); + this->Status.SetError(e.str()); return false; } return true; @@ -269,8 +270,8 @@ bool cmFileInstaller::HandleInstallDestination() // allow for / to be a valid destination if (destination.size() < 2 && destination != "/") { - this->FileCommand->SetError("called with inappropriate arguments. " - "No DESTINATION provided or ."); + this->Status.SetError("called with inappropriate arguments. " + "No DESTINATION provided or ."); return false; } @@ -300,7 +301,7 @@ bool cmFileInstaller::HandleInstallDestination() if (relative) { // This is relative path on unix or windows. Since we are doing // destdir, this case does not make sense. - this->FileCommand->SetError( + this->Status.SetError( "called with relative DESTINATION. This " "does not make sense when using DESTDIR. Specify " "absolute path or remove DESTDIR environment variable."); @@ -310,12 +311,12 @@ 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; - this->FileCommand->SetError(message); + 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; } } @@ -335,14 +336,14 @@ bool cmFileInstaller::HandleInstallDestination() if (!cmSystemTools::MakeDirectory(destination, default_dir_mode)) { std::string errstring = "cannot create directory: " + destination + ". Maybe need administrative privileges."; - this->FileCommand->SetError(errstring); + this->Status.SetError(errstring); return false; } } if (!cmSystemTools::FileIsDirectory(destination)) { std::string errstring = "INSTALL destination: " + destination + " is not a directory."; - this->FileCommand->SetError(errstring); + this->Status.SetError(errstring); return false; } } diff --git a/Source/cmFileInstaller.h b/Source/cmFileInstaller.h index 312529a..fd883ea 100644 --- a/Source/cmFileInstaller.h +++ b/Source/cmFileInstaller.h @@ -12,11 +12,11 @@ #include <string> #include <vector> -class cmFileCommand; +class cmExecutionStatus; struct cmFileInstaller : public cmFileCopier { - cmFileInstaller(cmFileCommand* command); + cmFileInstaller(cmExecutionStatus& status); ~cmFileInstaller() override; protected: 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/cmFileTimes.cxx b/Source/cmFileTimes.cxx index fd4f679..3824e9b 100644 --- a/Source/cmFileTimes.cxx +++ b/Source/cmFileTimes.cxx @@ -2,11 +2,12 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmFileTimes.h" -#include "cmAlgorithms.h" #include "cm_sys_stat.h" #include <utility> +#include "cm_memory.hxx" + #if defined(_WIN32) # include "cmSystemTools.h" # include <windows.h> diff --git a/Source/cmFileTimes.h b/Source/cmFileTimes.h index cbf0fe2..191d89e 100644 --- a/Source/cmFileTimes.h +++ b/Source/cmFileTimes.h @@ -5,7 +5,7 @@ #include "cmConfigure.h" // IWYU pragma: keep -#include <memory> // IWYU pragma: keep +#include <memory> #include <string> /** \class cmFileTimes diff --git a/Source/cmFindBase.cxx b/Source/cmFindBase.cxx index 42aff04..cdc5f63 100644 --- a/Source/cmFindBase.cxx +++ b/Source/cmFindBase.cxx @@ -13,6 +13,7 @@ #include "cmSearchPath.h" #include "cmState.h" #include "cmStateTypes.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" cmFindBase::cmFindBase() @@ -67,6 +68,9 @@ bool cmFindBase::ParseArguments(std::vector<std::string> const& argsIn) } this->AlreadyInCache = false; + // Find what search path locations have been enabled/disable + this->SelectDefaultSearchModes(); + // Find the current root path mode. this->SelectDefaultRootPathMode(); @@ -185,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); @@ -219,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); @@ -253,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); @@ -320,7 +318,7 @@ bool cmFindBase::CheckForVariableInCache() this->Makefile->GetDefinition(this->VariableName)) { cmState* state = this->Makefile->GetState(); const char* cacheEntry = state->GetCacheEntryValue(this->VariableName); - bool found = !cmSystemTools::IsNOTFOUND(cacheValue); + bool found = !cmIsNOTFOUND(cacheValue); bool cached = cacheEntry != nullptr; if (found) { // If the user specifies the entry on the command line without a diff --git a/Source/cmFindCommon.cxx b/Source/cmFindCommon.cxx index 954558f..9425f99 100644 --- a/Source/cmFindCommon.cxx +++ b/Source/cmFindCommon.cxx @@ -3,11 +3,13 @@ #include "cmFindCommon.h" #include <algorithm> +#include <array> #include <string.h> #include <utility> #include "cmAlgorithms.h" #include "cmMakefile.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" cmFindCommon::PathGroup cmFindCommon::PathGroup::All("ALL"); @@ -90,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") { @@ -144,6 +146,26 @@ void cmFindCommon::SelectDefaultMacMode() } } +void cmFindCommon::SelectDefaultSearchModes() +{ + const std::array<std::pair<bool&, std::string>, 5> search_paths = { + { { this->NoPackageRootPath, "CMAKE_FIND_USE_PACKAGE_ROOT_PATH" }, + { this->NoCMakePath, "CMAKE_FIND_USE_CMAKE_PATH" }, + { this->NoCMakeEnvironmentPath, + "CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH" }, + { this->NoSystemEnvironmentPath, + "CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH" }, + { this->NoCMakeSystemPath, "CMAKE_FIND_USE_CMAKE_SYSTEM_PATH" } } + }; + + for (auto& path : search_paths) { + const char* def = this->Makefile->GetDefinition(path.second); + if (def) { + path.first = !cmIsOn(def); + } + } +} + void cmFindCommon::RerootPaths(std::vector<std::string>& paths) { #if 0 @@ -174,7 +196,7 @@ void cmFindCommon::RerootPaths(std::vector<std::string>& paths) // Construct the list of path roots with no trailing slashes. std::vector<std::string> roots; if (rootPath) { - cmSystemTools::ExpandListArgument(rootPath, roots); + cmExpandList(rootPath, roots); } if (sysrootCompile) { roots.emplace_back(sysrootCompile); @@ -207,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); @@ -240,7 +261,7 @@ void cmFindCommon::GetIgnoredPaths(std::vector<std::string>& ignore) continue; } - cmSystemTools::ExpandListArgument(ignorePath, ignore); + cmExpandList(ignorePath, ignore); } for (std::string& i : ignore) { diff --git a/Source/cmFindCommon.h b/Source/cmFindCommon.h index 89ff174..d95eeb1 100644 --- a/Source/cmFindCommon.h +++ b/Source/cmFindCommon.h @@ -90,6 +90,9 @@ protected: /** Compute the current default bundle/framework search policy. */ void SelectDefaultMacMode(); + /** Compute the current default search modes based on global variables. */ + void SelectDefaultSearchModes(); + // Path arguments prior to path manipulation routines std::vector<std::string> UserHintsArgs; std::vector<std::string> UserGuessArgs; diff --git a/Source/cmFindFileCommand.h b/Source/cmFindFileCommand.h index 4309449..152b505 100644 --- a/Source/cmFindFileCommand.h +++ b/Source/cmFindFileCommand.h @@ -5,9 +5,10 @@ #include "cmConfigure.h" // IWYU pragma: keep -#include "cmFindPathCommand.h" +#include "cm_memory.hxx" -class cmCommand; +#include "cmCommand.h" +#include "cmFindPathCommand.h" /** \class cmFindFileCommand * \brief Define a command to search for an executable program. @@ -24,7 +25,10 @@ public: /** * This is a virtual constructor for the command. */ - cmCommand* Clone() override { return new cmFindFileCommand; } + std::unique_ptr<cmCommand> Clone() override + { + return cm::make_unique<cmFindFileCommand>(); + } }; #endif diff --git a/Source/cmFindLibraryCommand.cxx b/Source/cmFindLibraryCommand.cxx index 73d602d..924a14e 100644 --- a/Source/cmFindLibraryCommand.cxx +++ b/Source/cmFindLibraryCommand.cxx @@ -13,6 +13,7 @@ #include "cmMakefile.h" #include "cmState.h" #include "cmStateTypes.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" class cmExecutionStatus; @@ -237,8 +238,8 @@ cmFindLibraryHelper::cmFindLibraryHelper(cmMakefile* mf) this->Makefile->GetRequiredDefinition("CMAKE_FIND_LIBRARY_PREFIXES"); std::string const& suffixes_list = this->Makefile->GetRequiredDefinition("CMAKE_FIND_LIBRARY_SUFFIXES"); - cmSystemTools::ExpandListArgument(prefixes_list, this->Prefixes, true); - cmSystemTools::ExpandListArgument(suffixes_list, this->Suffixes, true); + cmExpandList(prefixes_list, this->Prefixes, true); + cmExpandList(suffixes_list, this->Suffixes, true); this->RegexFromList(this->PrefixRegexStr, this->Prefixes); this->RegexFromList(this->SuffixRegexStr, this->Suffixes); @@ -311,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) { @@ -348,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); @@ -374,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, @@ -465,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); } @@ -484,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/cmFindLibraryCommand.h b/Source/cmFindLibraryCommand.h index fb8a700..af17d60 100644 --- a/Source/cmFindLibraryCommand.h +++ b/Source/cmFindLibraryCommand.h @@ -8,9 +8,11 @@ #include <string> #include <vector> +#include "cm_memory.hxx" + +#include "cmCommand.h" #include "cmFindBase.h" -class cmCommand; class cmExecutionStatus; /** \class cmFindLibraryCommand @@ -27,7 +29,10 @@ public: /** * This is a virtual constructor for the command. */ - cmCommand* Clone() override { return new cmFindLibraryCommand; } + std::unique_ptr<cmCommand> Clone() override + { + return cm::make_unique<cmFindLibraryCommand>(); + } /** * This is called when the command is first encountered in diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx index 171fa77..9132760 100644 --- a/Source/cmFindPackageCommand.cxx +++ b/Source/cmFindPackageCommand.cxx @@ -13,12 +13,13 @@ #include <deque> #include <functional> #include <iterator> -#include <memory> // IWYU pragma: keep #include <sstream> #include <stdio.h> #include <string.h> #include <utility> +#include "cm_memory.hxx" + #include "cmAlgorithms.h" #include "cmMakefile.h" #include "cmMessageType.h" @@ -27,6 +28,7 @@ #include "cmSearchPath.h" #include "cmState.h" #include "cmStateTypes.h" +#include "cmStringAlgorithms.h" #include "cmVersion.h" #if defined(__HAIKU__) @@ -188,7 +190,12 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args, } // Check if User Package Registry should be disabled - if (this->Makefile->IsOn("CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY")) { + // The `CMAKE_FIND_USE_PACKAGE_REGISTRY` has + // priority over the deprecated CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY + if (const char* def = + this->Makefile->GetDefinition("CMAKE_FIND_USE_PACKAGE_REGISTRY")) { + this->NoUserRegistry = !cmIsOn(def); + } else if (this->Makefile->IsOn("CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY")) { this->NoUserRegistry = true; } @@ -219,6 +226,9 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args, this->SortDirection = strcmp(sd, "ASC") == 0 ? Asc : Dec; } + // Find what search path locations have been enabled/disable + this->SelectDefaultSearchModes(); + // Find the current root path mode. this->SelectDefaultRootPathMode(); @@ -398,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()) { @@ -448,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; @@ -488,7 +495,7 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args, // NEW behavior is to honor the <pkg>_ROOT variables. std::string const rootVar = this->Name + "_ROOT"; if (const char* pkgRoot = this->Makefile->GetDefinition(rootVar)) { - cmSystemTools::ExpandListArgument(pkgRoot, rootPaths, false); + cmExpandList(pkgRoot, rootPaths, false); } cmSystemTools::GetPath(rootPaths, rootVar.c_str()); } break; @@ -579,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()) { @@ -590,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)); } } @@ -624,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); @@ -656,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"); } } @@ -671,7 +671,9 @@ void cmFindPackageCommand::AddFindDefinition(const std::string& var, } else { this->OriginalDefs[var].exists = false; } - this->Makefile->AddDefinition(var, val); + if (val) { + this->Makefile->AddDefinition(var, val); + } } void cmFindPackageCommand::RestoreFindDefinitions() @@ -679,7 +681,7 @@ void cmFindPackageCommand::RestoreFindDefinitions() for (auto const& i : this->OriginalDefs) { OriginalDef const& od = i.second; if (od.exists) { - this->Makefile->AddDefinition(i.first, od.value.c_str()); + this->Makefile->AddDefinition(i.first, od.value); } else { this->Makefile->RemoveDefinition(i.first); } @@ -688,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()) { @@ -719,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); @@ -734,19 +733,13 @@ bool cmFindPackageCommand::HandlePackageMode( { this->ConsideredConfigs.clear(); - // Support old capitalization behavior. - std::string upperDir = cmSystemTools::UpperCase(this->Name); - std::string upperFound = cmSystemTools::UpperCase(this->Name); - upperDir += "_DIR"; - upperFound += "_FOUND"; - // Try to find the config file. const char* def = this->Makefile->GetDefinition(this->Variable); // Try to load the config file if the directory is known bool fileFound = false; if (this->UseConfigFiles) { - if (!cmSystemTools::IsOff(def)) { + if (!cmIsOff(def)) { // Get the directory from the variable value. std::string dir = def; cmSystemTools::ConvertToUnixSlashes(dir); @@ -766,7 +759,7 @@ bool cmFindPackageCommand::HandlePackageMode( } // Search for the config file if it is not already found. - if (cmSystemTools::IsOff(def) || !fileFound) { + if (cmIsOff(def) || !fileFound) { fileFound = this->FindConfig(); } @@ -779,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. @@ -872,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) { @@ -956,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.c_str()); + 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; @@ -981,11 +970,9 @@ bool cmFindPackageCommand::HandlePackageMode( sep = ";"; } - this->Makefile->AddDefinition(consideredConfigsVar, - consideredConfigFiles.c_str()); + this->Makefile->AddDefinition(consideredConfigsVar, consideredConfigFiles); - this->Makefile->AddDefinition(consideredVersionsVar, - consideredVersions.c_str()); + this->Makefile->AddDefinition(consideredVersionsVar, consideredVersions); return result; } @@ -1031,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); @@ -1080,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; } @@ -1095,7 +1079,7 @@ void cmFindPackageCommand::AppendToFoundProperty(bool found) if (foundProp && *foundProp) { std::string tmp = foundProp; - cmSystemTools::ExpandListArgument(tmp, foundContents, false); + cmExpandList(tmp, foundContents, false); std::vector<std::string>::iterator nameIt = std::find(foundContents.begin(), foundContents.end(), this->Name); if (nameIt != foundContents.end()) { @@ -1109,7 +1093,7 @@ void cmFindPackageCommand::AppendToFoundProperty(bool found) if (notFoundProp && *notFoundProp) { std::string tmp = notFoundProp; - cmSystemTools::ExpandListArgument(tmp, notFoundContents, false); + cmExpandList(tmp, notFoundContents, false); std::vector<std::string>::iterator nameIt = std::find(notFoundContents.begin(), notFoundContents.end(), this->Name); if (nameIt != notFoundContents.end()) { @@ -1134,45 +1118,38 @@ 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); const char* result = this->Makefile->GetDefinition(found); - bool packageFound = - ((cmSystemTools::IsOn(result)) || (cmSystemTools::IsOn(upperResult))); + bool packageFound = ((cmIsOn(result)) || (cmIsOn(upperResult))); this->AppendToFoundProperty(packageFound); // 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"); } @@ -1282,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]); } @@ -1425,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. @@ -1542,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()); } @@ -1570,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; @@ -1614,8 +1583,8 @@ bool cmFindPackageCommand::CheckVersionFile(std::string const& version_file, this->Makefile->RemoveDefinition("PACKAGE_VERSION_EXACT"); // Set the input variables. - this->Makefile->AddDefinition("PACKAGE_FIND_NAME", this->Name.c_str()); - this->Makefile->AddDefinition("PACKAGE_FIND_VERSION", this->Version.c_str()); + this->Makefile->AddDefinition("PACKAGE_FIND_NAME", this->Name); + this->Makefile->AddDefinition("PACKAGE_FIND_VERSION", this->Version); char buf[64]; sprintf(buf, "%u", this->VersionMajor); this->Makefile->AddDefinition("PACKAGE_FIND_VERSION_MAJOR", buf); @@ -1687,12 +1656,11 @@ 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 { - this->Makefile->AddDefinition(ver, this->VersionFound.c_str()); + this->Makefile->AddDefinition(ver, this->VersionFound); } // Store the version components. @@ -2036,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/cmFindPackageCommand.h b/Source/cmFindPackageCommand.h index 316ca0f..f6645ae 100644 --- a/Source/cmFindPackageCommand.h +++ b/Source/cmFindPackageCommand.h @@ -3,6 +3,7 @@ #ifndef cmFindPackageCommand_h #define cmFindPackageCommand_h +#include "cmCommand.h" #include "cmConfigure.h" // IWYU pragma: keep #include "cmPolicies.h" @@ -14,6 +15,8 @@ #include <string> #include <vector> +#include "cm_memory.hxx" + // IWYU insists we should forward-declare instead of including <functional>, // but we cannot forward-declare reliably because some C++ standard libraries // put the template in an inline namespace. @@ -27,7 +30,6 @@ namespace std { #include "cmFindCommon.h" -class cmCommand; class cmExecutionStatus; class cmSearchPath; @@ -65,7 +67,10 @@ public: /** * This is a virtual constructor for the command. */ - cmCommand* Clone() override { return new cmFindPackageCommand; } + std::unique_ptr<cmCommand> Clone() override + { + return cm::make_unique<cmFindPackageCommand>(); + } /** * This is called when the command is first encountered in 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/cmFindPathCommand.h b/Source/cmFindPathCommand.h index cb0db4c..89e2cef 100644 --- a/Source/cmFindPathCommand.h +++ b/Source/cmFindPathCommand.h @@ -8,9 +8,11 @@ #include <string> #include <vector> +#include "cm_memory.hxx" + +#include "cmCommand.h" #include "cmFindBase.h" -class cmCommand; class cmExecutionStatus; /** \class cmFindPathCommand @@ -27,7 +29,10 @@ public: /** * This is a virtual constructor for the command. */ - cmCommand* Clone() override { return new cmFindPathCommand; } + std::unique_ptr<cmCommand> Clone() override + { + return cm::make_unique<cmFindPathCommand>(); + } /** * This is called when the command is first encountered in diff --git a/Source/cmFindProgramCommand.cxx b/Source/cmFindProgramCommand.cxx index 782f746..a2db65c 100644 --- a/Source/cmFindProgramCommand.cxx +++ b/Source/cmFindProgramCommand.cxx @@ -4,6 +4,7 @@ #include "cmMakefile.h" #include "cmStateTypes.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" class cmExecutionStatus; @@ -71,11 +72,10 @@ struct cmFindProgramHelper bool CheckDirectoryForName(std::string const& path, std::string const& name) { for (std::string const& ext : this->Extensions) { - if (!ext.empty() && cmSystemTools::StringEndsWith(name, ext.c_str())) { + 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/cmFindProgramCommand.h b/Source/cmFindProgramCommand.h index 147936c..40e455e 100644 --- a/Source/cmFindProgramCommand.h +++ b/Source/cmFindProgramCommand.h @@ -8,9 +8,11 @@ #include <string> #include <vector> +#include "cm_memory.hxx" + +#include "cmCommand.h" #include "cmFindBase.h" -class cmCommand; class cmExecutionStatus; /** \class cmFindProgramCommand @@ -28,7 +30,10 @@ public: /** * This is a virtual constructor for the command. */ - cmCommand* Clone() override { return new cmFindProgramCommand; } + std::unique_ptr<cmCommand> Clone() override + { + return cm::make_unique<cmFindProgramCommand>(); + } /** * This is called when the command is first encountered in diff --git a/Source/cmForEachCommand.cxx b/Source/cmForEachCommand.cxx index 08003eb..f0633aa 100644 --- a/Source/cmForEachCommand.cxx +++ b/Source/cmForEachCommand.cxx @@ -2,21 +2,50 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmForEachCommand.h" -#include <memory> // IWYU pragma: keep #include <sstream> #include <stdio.h> #include <stdlib.h> +#include <utility> + +#include "cm_memory.hxx" +#include "cm_static_string_view.hxx" +#include "cm_string_view.hxx" -#include "cmAlgorithms.h" #include "cmExecutionStatus.h" +#include "cmFunctionBlocker.h" +#include "cmListFileCache.h" #include "cmMakefile.h" #include "cmMessageType.h" #include "cmRange.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" +namespace { +bool HandleInMode(std::vector<std::string> const& args, cmMakefile& makefile); + +class cmForEachFunctionBlocker : public cmFunctionBlocker +{ +public: + cmForEachFunctionBlocker(cmMakefile* mf); + ~cmForEachFunctionBlocker() override; + + cm::string_view StartCommandName() const override { return "foreach"_s; } + cm::string_view EndCommandName() const override { return "endforeach"_s; } + + bool ArgumentsMatch(cmListFileFunction const& lff, + cmMakefile& mf) const override; + + bool Replay(std::vector<cmListFileFunction> functions, + cmExecutionStatus& inStatus) override; + + std::vector<std::string> Args; + +private: + cmMakefile* Makefile; +}; + cmForEachFunctionBlocker::cmForEachFunctionBlocker(cmMakefile* mf) : Makefile(mf) - , Depth(0) { this->Makefile->PushLoopBlock(); } @@ -26,102 +55,71 @@ cmForEachFunctionBlocker::~cmForEachFunctionBlocker() this->Makefile->PopLoopBlock(); } -bool cmForEachFunctionBlocker::IsFunctionBlocked(const cmListFileFunction& lff, - cmMakefile& mf, - cmExecutionStatus& inStatus) +bool cmForEachFunctionBlocker::ArgumentsMatch(cmListFileFunction const& lff, + cmMakefile& mf) const { - if (lff.Name.Lower == "foreach") { - // record the number of nested foreach commands - this->Depth++; - } else if (lff.Name.Lower == "endforeach") { - // if this is the endofreach for this statement - if (!this->Depth) { - // Remove the function blocker for this scope or bail. - std::unique_ptr<cmFunctionBlocker> fb( - mf.RemoveFunctionBlocker(this, lff)); - if (!fb) { - return false; - } + std::vector<std::string> expandedArguments; + mf.ExpandArguments(lff.Arguments, expandedArguments); + return expandedArguments.empty() || expandedArguments[0] == this->Args[0]; +} - // at end of for each execute recorded commands - // store the old value - std::string oldDef; - if (mf.GetDefinition(this->Args[0])) { - oldDef = mf.GetDefinition(this->Args[0]); - } +bool cmForEachFunctionBlocker::Replay( + std::vector<cmListFileFunction> functions, cmExecutionStatus& inStatus) +{ + cmMakefile& mf = inStatus.GetMakefile(); + // at end of for each execute recorded commands + // store the old value + std::string oldDef; + if (mf.GetDefinition(this->Args[0])) { + oldDef = mf.GetDefinition(this->Args[0]); + } - for (std::string const& arg : cmMakeRange(this->Args).advance(1)) { - // set the variable to the loop value - mf.AddDefinition(this->Args[0], arg.c_str()); - // Invoke all the functions that were collected in the block. - cmExecutionStatus status; - for (cmListFileFunction const& func : this->Functions) { - status.Clear(); - mf.ExecuteCommand(func, status); - if (status.GetReturnInvoked()) { - inStatus.SetReturnInvoked(); - // restore the variable to its prior value - mf.AddDefinition(this->Args[0], oldDef.c_str()); - return true; - } - if (status.GetBreakInvoked()) { - // restore the variable to its prior value - mf.AddDefinition(this->Args[0], oldDef.c_str()); - return true; - } - if (status.GetContinueInvoked()) { - break; - } - if (cmSystemTools::GetFatalErrorOccured()) { - return true; - } - } + for (std::string const& arg : cmMakeRange(this->Args).advance(1)) { + // set the variable to the loop value + mf.AddDefinition(this->Args[0], arg); + // Invoke all the functions that were collected in the block. + for (cmListFileFunction const& func : functions) { + cmExecutionStatus status(mf); + mf.ExecuteCommand(func, status); + if (status.GetReturnInvoked()) { + inStatus.SetReturnInvoked(); + // restore the variable to its prior value + mf.AddDefinition(this->Args[0], oldDef); + return true; + } + if (status.GetBreakInvoked()) { + // restore the variable to its prior value + mf.AddDefinition(this->Args[0], oldDef); + return true; + } + if (status.GetContinueInvoked()) { + break; + } + if (cmSystemTools::GetFatalErrorOccured()) { + return true; } - - // restore the variable to its prior value - mf.AddDefinition(this->Args[0], oldDef.c_str()); - return true; } - // close out a nested foreach - this->Depth--; } - // record the command - this->Functions.push_back(lff); - - // always return true + // restore the variable to its prior value + mf.AddDefinition(this->Args[0], oldDef); return true; } - -bool cmForEachFunctionBlocker::ShouldRemove(const cmListFileFunction& lff, - cmMakefile& mf) -{ - if (lff.Name.Lower == "endforeach") { - std::vector<std::string> expandedArguments; - mf.ExpandArguments(lff.Arguments, expandedArguments); - // if the endforeach has arguments then make sure - // they match the begin foreach arguments - if ((expandedArguments.empty() || - (expandedArguments[0] == this->Args[0]))) { - return true; - } - } - return false; } -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 f = 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; @@ -151,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; @@ -168,23 +166,23 @@ bool cmForEachCommand::InitialPass(std::vector<std::string> const& args, break; } } - f->Args = range; + fb->Args = range; } else { - f->Args = args; + fb->Args = args; } } else { - f->Args = args; + fb->Args = args; } - this->Makefile->AddFunctionBlocker(f.release()); + 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) { - std::unique_ptr<cmForEachFunctionBlocker> f( - new cmForEachFunctionBlocker(this->Makefile)); - f->Args.push_back(args[0]); + auto fb = cm::make_unique<cmForEachFunctionBlocker>(&makefile); + fb->Args.push_back(args[0]); enum Doing { @@ -195,26 +193,27 @@ bool cmForEachCommand::HandleInMode(std::vector<std::string> const& args) Doing doing = DoingNone; for (unsigned int i = 2; i < args.size(); ++i) { if (doing == DoingItems) { - f->Args.push_back(args[i]); + fb->Args.push_back(args[i]); } else if (args[i] == "LISTS") { doing = DoingLists; } 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) { - cmSystemTools::ExpandListArgument(value, f->Args, true); + cmExpandList(value, fb->Args, true); } } else { 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(f.release()); // TODO: pass unique_ptr + makefile.AddFunctionBlocker(std::move(fb)); return true; } +} diff --git a/Source/cmForEachCommand.h b/Source/cmForEachCommand.h index 5131a4f..1feb965 100644 --- a/Source/cmForEachCommand.h +++ b/Source/cmForEachCommand.h @@ -8,48 +8,9 @@ #include <string> #include <vector> -#include "cmCommand.h" -#include "cmFunctionBlocker.h" -#include "cmListFileCache.h" - class cmExecutionStatus; -class cmMakefile; - -class cmForEachFunctionBlocker : public cmFunctionBlocker -{ -public: - cmForEachFunctionBlocker(cmMakefile* mf); - ~cmForEachFunctionBlocker() override; - bool IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile& mf, - cmExecutionStatus&) override; - bool ShouldRemove(const cmListFileFunction& lff, cmMakefile& mf) override; - - std::vector<std::string> Args; - std::vector<cmListFileFunction> Functions; - -private: - cmMakefile* Makefile; - int Depth; -}; /// Starts foreach() ... endforeach() block -class cmForEachCommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - cmCommand* Clone() override { return new 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/cmFunctionBlocker.cxx b/Source/cmFunctionBlocker.cxx new file mode 100644 index 0000000..5778a71 --- /dev/null +++ b/Source/cmFunctionBlocker.cxx @@ -0,0 +1,46 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#include "cmFunctionBlocker.h" + +#include <cassert> +#include <sstream> +#include <utility> + +#include "cmExecutionStatus.h" +#include "cmMakefile.h" +#include "cmMessageType.h" + +bool cmFunctionBlocker::IsFunctionBlocked(const cmListFileFunction& lff, + cmExecutionStatus& status) +{ + if (lff.Name.Lower == this->StartCommandName()) { + this->ScopeDepth++; + } else if (lff.Name.Lower == this->EndCommandName()) { + this->ScopeDepth--; + if (this->ScopeDepth == 0U) { + cmMakefile& mf = status.GetMakefile(); + auto self = mf.RemoveFunctionBlocker(); + assert(self.get() == this); + + if (!this->ArgumentsMatch(lff, mf)) { + cmListFileContext const& lfc = this->GetStartingContext(); + cmListFileContext closingContext = + cmListFileContext::FromCommandContext(lff, lfc.FilePath); + std::ostringstream e; + /* clang-format off */ + e << "A logical block opening on the line\n" + << " " << lfc << "\n" + << "closes on the line\n" + << " " << closingContext << "\n" + << "with mis-matching arguments."; + /* clang-format on */ + mf.IssueMessage(MessageType::AUTHOR_WARNING, e.str()); + } + + return this->Replay(std::move(this->Functions), status); + } + } + + this->Functions.push_back(lff); + return true; +} diff --git a/Source/cmFunctionBlocker.h b/Source/cmFunctionBlocker.h index cd6b05d..87bdccd 100644 --- a/Source/cmFunctionBlocker.h +++ b/Source/cmFunctionBlocker.h @@ -3,6 +3,12 @@ #ifndef cmFunctionBlocker_h #define cmFunctionBlocker_h +#include "cmConfigure.h" // IWYU pragma: keep + +#include <vector> + +#include "cm_string_view.hxx" + #include "cmListFileCache.h" class cmExecutionStatus; @@ -14,17 +20,8 @@ public: /** * should a function be blocked */ - virtual bool IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile& mf, - cmExecutionStatus& status) = 0; - - /** - * should this function blocker be removed, useful when one function adds a - * blocker and another must remove it - */ - virtual bool ShouldRemove(const cmListFileFunction&, cmMakefile&) - { - return false; - } + bool IsFunctionBlocked(cmListFileFunction const& lff, + cmExecutionStatus& status); virtual ~cmFunctionBlocker() = default; @@ -39,7 +36,19 @@ public: } private: + virtual cm::string_view StartCommandName() const = 0; + virtual cm::string_view EndCommandName() const = 0; + + virtual bool ArgumentsMatch(cmListFileFunction const& lff, + cmMakefile& mf) const = 0; + + virtual bool Replay(std::vector<cmListFileFunction> functions, + cmExecutionStatus& status) = 0; + +private: cmListFileContext StartingContext; + std::vector<cmListFileFunction> Functions; + unsigned int ScopeDepth = 1; }; #endif diff --git a/Source/cmFunctionCommand.cxx b/Source/cmFunctionCommand.cxx index 9067a5f..9420541 100644 --- a/Source/cmFunctionCommand.cxx +++ b/Source/cmFunctionCommand.cxx @@ -3,88 +3,79 @@ #include "cmFunctionCommand.h" #include <sstream> +#include <utility> + +#include "cm_memory.hxx" +#include "cm_static_string_view.hxx" +#include "cm_string_view.hxx" #include "cmAlgorithms.h" #include "cmExecutionStatus.h" +#include "cmFunctionBlocker.h" +#include "cmListFileCache.h" #include "cmMakefile.h" #include "cmPolicies.h" #include "cmRange.h" #include "cmState.h" +#include "cmStringAlgorithms.h" +namespace { // define the class for function commands -class cmFunctionHelperCommand : public cmCommand +class cmFunctionHelperCommand { public: /** - * This is a virtual constructor for the command. - */ - cmCommand* Clone() override - { - cmFunctionHelperCommand* newC = new cmFunctionHelperCommand; - // we must copy when we clone - newC->Args = this->Args; - newC->Functions = this->Functions; - newC->Policies = this->Policies; - newC->FilePath = this->FilePath; - return newC; - } - - /** * This is called when the command is first encountered in * the CMakeLists.txt file. */ - bool InvokeInitialPass(const std::vector<cmListFileArgument>& args, - cmExecutionStatus&) override; - - bool InitialPass(std::vector<std::string> const&, - cmExecutionStatus&) override - { - return false; - } + bool operator()(std::vector<cmListFileArgument> const& args, + cmExecutionStatus& inStatus) const; std::vector<std::string> Args; std::vector<cmListFileFunction> Functions; cmPolicies::PolicyMap Policies; std::string FilePath; }; +} -bool cmFunctionHelperCommand::InvokeInitialPass( - const std::vector<cmListFileArgument>& args, cmExecutionStatus& inStatus) +bool cmFunctionHelperCommand::operator()( + std::vector<cmListFileArgument> const& args, + cmExecutionStatus& inStatus) const { + cmMakefile& makefile = inStatus.GetMakefile(); + // Expand the argument list to the function. std::vector<std::string> expandedArgs; - this->Makefile->ExpandArguments(args, expandedArgs); + makefile.ExpandArguments(args, expandedArgs); // 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]; - this->SetError(errorMsg); + std::string errorMsg = cmStrCat( + "Function invoked with incorrect arguments for function named: ", + this->Args[0]); + inStatus.SetError(errorMsg); return false; } - cmMakefile::FunctionPushPop functionScope(this->Makefile, this->FilePath, + cmMakefile::FunctionPushPop functionScope(&makefile, this->FilePath, this->Policies); // set the value of argc - std::ostringstream strStream; - strStream << expandedArgs.size(); - this->Makefile->AddDefinition("ARGC", strStream.str().c_str()); - this->Makefile->MarkVariableAsUsed("ARGC"); + makefile.AddDefinition("ARGC", std::to_string(expandedArgs.size())); + makefile.MarkVariableAsUsed("ARGC"); // set the values for ARGV0 ARGV1 ... for (unsigned int t = 0; t < expandedArgs.size(); ++t) { std::ostringstream tmpStream; tmpStream << "ARGV" << t; - this->Makefile->AddDefinition(tmpStream.str(), expandedArgs[t].c_str()); - this->Makefile->MarkVariableAsUsed(tmpStream.str()); + makefile.AddDefinition(tmpStream.str(), expandedArgs[t]); + makefile.MarkVariableAsUsed(tmpStream.str()); } // define the formal arguments for (unsigned int j = 1; j < this->Args.size(); ++j) { - this->Makefile->AddDefinition(this->Args[j], expandedArgs[j - 1].c_str()); + makefile.AddDefinition(this->Args[j], expandedArgs[j - 1]); } // define ARGV and ARGN @@ -92,17 +83,16 @@ bool cmFunctionHelperCommand::InvokeInitialPass( std::vector<std::string>::const_iterator eit = expandedArgs.begin() + (this->Args.size() - 1); std::string argnDef = cmJoin(cmMakeRange(eit, expandedArgs.end()), ";"); - this->Makefile->AddDefinition("ARGV", argvDef.c_str()); - this->Makefile->MarkVariableAsUsed("ARGV"); - this->Makefile->AddDefinition("ARGN", argnDef.c_str()); - this->Makefile->MarkVariableAsUsed("ARGN"); + makefile.AddDefinition("ARGV", argvDef); + makefile.MarkVariableAsUsed("ARGV"); + makefile.AddDefinition("ARGN", argnDef); + makefile.MarkVariableAsUsed("ARGN"); // Invoke all the functions that were collected in the block. // for each function for (cmListFileFunction const& func : this->Functions) { - cmExecutionStatus status; - if (!this->Makefile->ExecuteCommand(func, status) || - status.GetNestedError()) { + cmExecutionStatus status(makefile); + if (!makefile.ExecuteCommand(func, status) || status.GetNestedError()) { // The error message should have already included the call stack // so we do not need to report an error here. functionScope.Quiet(); @@ -118,66 +108,57 @@ bool cmFunctionHelperCommand::InvokeInitialPass( return true; } -bool cmFunctionFunctionBlocker::IsFunctionBlocked( - const cmListFileFunction& lff, cmMakefile& mf, cmExecutionStatus&) +class cmFunctionFunctionBlocker : public cmFunctionBlocker { - // record commands until we hit the ENDFUNCTION - // at the ENDFUNCTION call we shift gears and start looking for invocations - if (lff.Name.Lower == "function") { - this->Depth++; - } else if (lff.Name.Lower == "endfunction") { - // if this is the endfunction for this function then execute - if (!this->Depth) { - // create a new command and add it to cmake - cmFunctionHelperCommand* f = new cmFunctionHelperCommand(); - f->Args = this->Args; - f->Functions = this->Functions; - f->FilePath = this->GetStartingContext().FilePath; - mf.RecordPolicies(f->Policies); - mf.GetState()->AddScriptedCommand(this->Args[0], f); - // remove the function blocker now that the function is defined - mf.RemoveFunctionBlocker(this, lff); - return true; - } - // decrement for each nested function that ends - this->Depth--; - } +public: + cm::string_view StartCommandName() const override { return "function"_s; } + cm::string_view EndCommandName() const override { return "endfunction"_s; } - // if it wasn't an endfunction and we are not executing then we must be - // recording - this->Functions.push_back(lff); - return true; -} + bool ArgumentsMatch(cmListFileFunction const&, + cmMakefile& mf) const override; + + bool Replay(std::vector<cmListFileFunction> functions, + cmExecutionStatus& status) override; -bool cmFunctionFunctionBlocker::ShouldRemove(const cmListFileFunction& lff, - cmMakefile& mf) + std::vector<std::string> Args; +}; + +bool cmFunctionFunctionBlocker::ArgumentsMatch(cmListFileFunction const& lff, + cmMakefile& mf) const { - if (lff.Name.Lower == "endfunction") { - std::vector<std::string> expandedArguments; - mf.ExpandArguments(lff.Arguments, expandedArguments, - this->GetStartingContext().FilePath.c_str()); - // if the endfunction has arguments then make sure - // they match the ones in the opening function command - if ((expandedArguments.empty() || - (expandedArguments[0] == this->Args[0]))) { - return true; - } - } + std::vector<std::string> expandedArguments; + mf.ExpandArguments(lff.Arguments, expandedArguments, + this->GetStartingContext().FilePath.c_str()); + return expandedArguments.empty() || expandedArguments[0] == this->Args[0]; +} - return false; +bool cmFunctionFunctionBlocker::Replay( + std::vector<cmListFileFunction> functions, cmExecutionStatus& status) +{ + cmMakefile& mf = status.GetMakefile(); + // create a new command and add it to cmake + cmFunctionHelperCommand f; + f.Args = this->Args; + f.Functions = std::move(functions); + f.FilePath = this->GetStartingContext().FilePath; + mf.RecordPolicies(f.Policies); + mf.GetState()->AddScriptedCommand(this->Args[0], std::move(f)); + 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; } // create a function blocker - cmFunctionFunctionBlocker* f = new cmFunctionFunctionBlocker(); - cmAppend(f->Args, args); - this->Makefile->AddFunctionBlocker(f); + { + auto fb = cm::make_unique<cmFunctionFunctionBlocker>(); + cmAppend(fb->Args, args); + status.GetMakefile().AddFunctionBlocker(std::move(fb)); + } return true; } diff --git a/Source/cmFunctionCommand.h b/Source/cmFunctionCommand.h index 8b37df0..d6b549c 100644 --- a/Source/cmFunctionCommand.h +++ b/Source/cmFunctionCommand.h @@ -8,40 +8,10 @@ #include <string> #include <vector> -#include "cmCommand.h" -#include "cmFunctionBlocker.h" -#include "cmListFileCache.h" - class cmExecutionStatus; -class cmMakefile; - -class cmFunctionFunctionBlocker : public cmFunctionBlocker -{ -public: - bool IsFunctionBlocked(const cmListFileFunction&, cmMakefile& mf, - cmExecutionStatus&) override; - bool ShouldRemove(const cmListFileFunction&, cmMakefile& mf) override; - - std::vector<std::string> Args; - std::vector<cmListFileFunction> Functions; - int Depth = 0; -}; /// Starts function() ... endfunction() block -class cmFunctionCommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - cmCommand* Clone() override { return new 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/cmGeneratedFileStream.cxx b/Source/cmGeneratedFileStream.cxx index 2f47788..7475e9f 100644 --- a/Source/cmGeneratedFileStream.cxx +++ b/Source/cmGeneratedFileStream.cxx @@ -6,14 +6,14 @@ #include "cmSystemTools.h" -#if defined(CMAKE_BUILD_WITH_CMAKE) +#if !defined(CMAKE_BOOTSTRAP) # include "cm_codecvt.hxx" # include "cm_zlib.h" #endif cmGeneratedFileStream::cmGeneratedFileStream(Encoding encoding) { -#ifdef CMAKE_BUILD_WITH_CMAKE +#ifndef CMAKE_BOOTSTRAP if (encoding != codecvt::None) { imbue(std::locale(getloc(), new codecvt(encoding))); } @@ -32,7 +32,7 @@ cmGeneratedFileStream::cmGeneratedFileStream(std::string const& name, cmSystemTools::Error("Cannot open file for write: " + this->TempName); cmSystemTools::ReportLastSystemError(""); } -#ifdef CMAKE_BUILD_WITH_CMAKE +#ifndef CMAKE_BOOTSTRAP if (encoding != codecvt::None) { imbue(std::locale(getloc(), new codecvt(encoding))); } @@ -169,7 +169,7 @@ bool cmGeneratedFileStreamBase::Close() return replaced; } -#ifdef CMAKE_BUILD_WITH_CMAKE +#ifndef CMAKE_BOOTSTRAP int cmGeneratedFileStreamBase::CompressFile(std::string const& oldname, std::string const& newname) { diff --git a/Source/cmGeneratorExpression.cxx b/Source/cmGeneratorExpression.cxx index 175a26d..133a72b 100644 --- a/Source/cmGeneratorExpression.cxx +++ b/Source/cmGeneratorExpression.cxx @@ -3,7 +3,7 @@ #include "cmGeneratorExpression.h" #include "cmsys/RegularExpression.hxx" -#include <memory> // IWYU pragma: keep +#include <memory> #include <utility> #include "assert.h" @@ -13,6 +13,7 @@ #include "cmGeneratorExpressionEvaluator.h" #include "cmGeneratorExpressionLexer.h" #include "cmGeneratorExpressionParser.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" cmGeneratorExpression::cmGeneratorExpression(cmListFileBacktrace backtrace) @@ -294,7 +295,7 @@ void cmGeneratorExpression::Split(const std::string& input, preGenex = input.substr(startPos + 1, pos - startPos - 1); } if (!part.empty()) { - cmSystemTools::ExpandListArgument(part, output); + cmExpandList(part, output); } } pos += 2; @@ -327,7 +328,7 @@ void cmGeneratorExpression::Split(const std::string& input, lastPos = pos; } if (lastPos < input.size()) { - cmSystemTools::ExpandListArgument(input.substr(lastPos), output); + cmExpandList(input.substr(lastPos), output); } } diff --git a/Source/cmGeneratorExpression.h b/Source/cmGeneratorExpression.h index fd36c4b..ef76651 100644 --- a/Source/cmGeneratorExpression.h +++ b/Source/cmGeneratorExpression.h @@ -8,7 +8,7 @@ #include "cmListFileCache.h" #include <map> -#include <memory> // IWYU pragma: keep +#include <memory> #include <set> #include <string> #include <utility> diff --git a/Source/cmGeneratorExpressionDAGChecker.cxx b/Source/cmGeneratorExpressionDAGChecker.cxx index 728f2a4..df2227f 100644 --- a/Source/cmGeneratorExpressionDAGChecker.cxx +++ b/Source/cmGeneratorExpressionDAGChecker.cxx @@ -2,12 +2,12 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmGeneratorExpressionDAGChecker.h" -#include "cmAlgorithms.h" #include "cmGeneratorExpressionContext.h" #include "cmGeneratorExpressionEvaluator.h" #include "cmGeneratorTarget.h" #include "cmLocalGenerator.h" #include "cmMessageType.h" +#include "cmStringAlgorithms.h" #include "cmake.h" #include <sstream> @@ -68,9 +68,7 @@ void cmGeneratorExpressionDAGChecker::Initialize() return; } } - const_cast<cmGeneratorExpressionDAGChecker*>(top) - ->Seen[this->Target] - .insert(this->Property); + top->Seen[this->Target].insert(this->Property); } } diff --git a/Source/cmGeneratorExpressionDAGChecker.h b/Source/cmGeneratorExpressionDAGChecker.h index e1fba5e..6d7d6ef 100644 --- a/Source/cmGeneratorExpressionDAGChecker.h +++ b/Source/cmGeneratorExpressionDAGChecker.h @@ -88,7 +88,7 @@ private: const cmGeneratorExpressionDAGChecker* const Parent; cmGeneratorTarget const* Target; const std::string Property; - std::map<cmGeneratorTarget const*, std::set<std::string>> Seen; + mutable std::map<cmGeneratorTarget const*, std::set<std::string>> Seen; const GeneratorExpressionContent* const Content; const cmListFileBacktrace Backtrace; Result CheckResult; diff --git a/Source/cmGeneratorExpressionEvaluationFile.cxx b/Source/cmGeneratorExpressionEvaluationFile.cxx index 326cb0e..11c2dcc 100644 --- a/Source/cmGeneratorExpressionEvaluationFile.cxx +++ b/Source/cmGeneratorExpressionEvaluationFile.cxx @@ -3,7 +3,7 @@ #include "cmGeneratorExpressionEvaluationFile.h" #include "cmsys/FStream.hxx" -#include <memory> // IWYU pragma: keep +#include <memory> #include <sstream> #include <utility> diff --git a/Source/cmGeneratorExpressionEvaluationFile.h b/Source/cmGeneratorExpressionEvaluationFile.h index 89a2390..06ebeac 100644 --- a/Source/cmGeneratorExpressionEvaluationFile.h +++ b/Source/cmGeneratorExpressionEvaluationFile.h @@ -6,7 +6,7 @@ #include "cmConfigure.h" // IWYU pragma: keep #include <map> -#include <memory> // IWYU pragma: keep +#include <memory> #include <string> #include <vector> diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx index a60c75c..667f4a0 100644 --- a/Source/cmGeneratorExpressionNode.cxx +++ b/Source/cmGeneratorExpressionNode.cxx @@ -19,10 +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" @@ -33,7 +34,7 @@ #include <errno.h> #include <iterator> #include <map> -#include <memory> // IWYU pragma: keep +#include <memory> #include <set> #include <sstream> #include <stdlib.h> @@ -168,7 +169,7 @@ static const struct BoolNode : public cmGeneratorExpressionNode const GeneratorExpressionContent* /*content*/, cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override { - return !cmSystemTools::IsOff(parameters.front()) ? "1" : "0"; + return !cmIsOff(parameters.front()) ? "1" : "0"; } } boolNode; @@ -274,17 +275,18 @@ 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: if (parameters.front().empty()) { check = true; - cmSystemTools::ExpandListArgument(parameters[1], checkValues, true); + cmExpandList(parameters[1], checkValues, true); } CM_FALLTHROUGH; case cmPolicies::OLD: - cmSystemTools::ExpandListArgument(parameters[1], values); + cmExpandList(parameters[1], values); if (check && values != checkValues) { std::ostringstream e; e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0085) @@ -301,14 +303,11 @@ static const struct InListNode : public cmGeneratorExpressionNode case cmPolicies::REQUIRED_IF_USED: case cmPolicies::REQUIRED_ALWAYS: case cmPolicies::NEW: - cmSystemTools::ExpandListArgument(parameters[1], values, true); + cmExpandList(parameters[1], values, true); break; } - return std::find(values.cbegin(), values.cend(), parameters.front()) == - values.cend() - ? "0" - : "1"; + return cmContains(values, parameters.front()) ? "1" : "0"; } } inListNode; @@ -346,8 +345,9 @@ static const struct FilterNode : public cmGeneratorExpressionNode return {}; } - std::vector<std::string> values, result; - cmSystemTools::ExpandListArgument(parameters.front(), values, true); + 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), [&re, exclude](std::string const& input) { @@ -375,8 +375,7 @@ static const struct RemoveDuplicatesNode : public cmGeneratorExpressionNode "$<REMOVE_DUPLICATES:...> expression requires one parameter"); } - std::vector<std::string> values; - cmSystemTools::ExpandListArgument(parameters.front(), values, true); + std::vector<std::string> values = cmExpandedList(parameters.front(), true); auto valuesEnd = cmRemoveDuplicates(values); auto valuesBegin = values.cbegin(); @@ -684,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: @@ -909,15 +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)) { - cmSystemTools::ExpandListArgument(cmSystemTools::UpperCase(mapValue), - mappedConfigs); - return std::find(mappedConfigs.begin(), mappedConfigs.end(), - cmSystemTools::UpperCase(parameters.front())) != - mappedConfigs.end() + cmExpandList(cmSystemTools::UpperCase(mapValue), mappedConfigs); + 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; - cmSystemTools::ExpandListArgument(parameters.front(), list); + std::vector<std::string> list = cmExpandedList(parameters.front()); return cmJoin(list, parameters[1]); } } joinNode; @@ -1038,45 +1034,38 @@ static const struct CompileLanguageAndIdNode : public cmGeneratorExpressionNode } } languageAndIdNode; -#define TRANSITIVE_PROPERTY_NAME(PROPERTY) , "INTERFACE_" #PROPERTY - -static const char* targetPropertyTransitiveWhitelist[] = { - nullptr CM_FOR_EACH_TRANSITIVE_PROPERTY_NAME(TRANSITIVE_PROPERTY_NAME) -}; - -#undef TRANSITIVE_PROPERTY_NAME - -template <typename T> std::string getLinkedTargetsContent( - std::vector<T> const& libraries, cmGeneratorTarget const* target, - cmGeneratorTarget const* headTarget, cmGeneratorExpressionContext* context, - cmGeneratorExpressionDAGChecker* dagChecker, - const std::string& interfacePropertyName) -{ - std::string linkedTargetsContent; - std::string sep; - std::string depString; - for (T const& l : libraries) { - // Broken code can have a target in its own link interface. - // Don't follow such link interface entries so as not to create a - // self-referencing loop. - if (l.Target && l.Target != target) { - std::string uniqueName = - target->GetGlobalGenerator()->IndexGeneratorTargetUniquely(l.Target); - depString += sep + "$<TARGET_PROPERTY:" + std::move(uniqueName) + "," + - interfacePropertyName + ">"; - sep = ";"; - } - } - if (!depString.empty()) { - linkedTargetsContent = - cmGeneratorExpressionNode::EvaluateDependentExpression( - depString, target->GetLocalGenerator(), context, headTarget, target, - dagChecker); - } - linkedTargetsContent = - cmGeneratorExpression::StripEmptyListElements(linkedTargetsContent); - return linkedTargetsContent; + cmGeneratorTarget const* target, std::string const& prop, + cmGeneratorExpressionContext* context, + cmGeneratorExpressionDAGChecker* dagChecker) +{ + std::string result; + if (cmLinkImplementationLibraries const* impl = + target->GetLinkImplementationLibraries(context->Config)) { + for (cmLinkImplItem const& lib : impl->Libraries) { + if (lib.Target) { + // Pretend $<TARGET_PROPERTY:lib.Target,prop> appeared in our + // caller's property and hand-evaluate it as if it were compiled. + // Create a context as cmCompiledGeneratorExpression::Evaluate does. + cmGeneratorExpressionContext libContext( + target->GetLocalGenerator(), context->Config, context->Quiet, target, + target, context->EvaluateForBuildsystem, lib.Backtrace, + context->Language); + std::string libResult = + lib.Target->EvaluateInterfaceProperty(prop, &libContext, dagChecker); + if (!libResult.empty()) { + if (result.empty()) { + result = std::move(libResult); + } else { + result.reserve(result.size() + 1 + libResult.size()); + result += ";"; + result += libResult; + } + } + } + } + } + return result; } static const struct TargetPropertyNode : public cmGeneratorExpressionNode @@ -1116,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]; @@ -1205,44 +1195,37 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode return target->GetLinkerLanguage(context->Config); } - cmGeneratorExpressionDAGChecker dagChecker( - context->Backtrace, target, propertyName, content, dagCheckerParent); + std::string interfacePropertyName; + bool isInterfaceProperty = false; - switch (dagChecker.Check()) { - case cmGeneratorExpressionDAGChecker::SELF_REFERENCE: - dagChecker.ReportError(context, content->GetOriginalExpression()); - return std::string(); - case cmGeneratorExpressionDAGChecker::CYCLIC_REFERENCE: - // No error. We just skip cyclic references. - return std::string(); - case cmGeneratorExpressionDAGChecker::ALREADY_SEEN: - for (size_t i = 1; i < cm::size(targetPropertyTransitiveWhitelist); - ++i) { - if (targetPropertyTransitiveWhitelist[i] == propertyName) { - // No error. We're not going to find anything new here. - return std::string(); - } - } - case cmGeneratorExpressionDAGChecker::DAG: - break; - } +#define POPULATE_INTERFACE_PROPERTY_NAME(prop) \ + if (propertyName == #prop) { \ + interfacePropertyName = "INTERFACE_" #prop; \ + } else if (propertyName == "INTERFACE_" #prop) { \ + interfacePropertyName = "INTERFACE_" #prop; \ + isInterfaceProperty = true; \ + } else - std::string prop; - bool haveProp = false; - if (const char* p = target->GetProperty(propertyName)) { - prop = p; - haveProp = true; + CM_FOR_EACH_TRANSITIVE_PROPERTY_NAME(POPULATE_INTERFACE_PROPERTY_NAME) + // Note that the above macro terminates with an else + /* else */ if (cmHasLiteralPrefix(propertyName, "COMPILE_DEFINITIONS_")) { + cmPolicies::PolicyStatus polSt = + context->LG->GetPolicyStatus(cmPolicies::CMP0043); + if (polSt == cmPolicies::WARN || polSt == cmPolicies::OLD) { + interfacePropertyName = "INTERFACE_COMPILE_DEFINITIONS"; + } } +#undef POPULATE_INTERFACE_PROPERTY_NAME + + bool evaluatingLinkLibraries = false; if (dagCheckerParent) { if (dagCheckerParent->EvaluatingGenexExpression() || dagCheckerParent->EvaluatingPICExpression()) { // No check required. } else if (dagCheckerParent->EvaluatingLinkLibraries()) { -#define TRANSITIVE_PROPERTY_COMPARE(PROPERTY) \ - (#PROPERTY == propertyName || "INTERFACE_" #PROPERTY == propertyName) || - if (CM_FOR_EACH_TRANSITIVE_PROPERTY_NAME( - TRANSITIVE_PROPERTY_COMPARE) false) { // NOLINT(*) + evaluatingLinkLibraries = true; + if (!interfacePropertyName.empty()) { reportError( context, content->GetOriginalExpression(), "$<TARGET_PROPERTY:...> expression in link libraries " @@ -1250,69 +1233,47 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode "over the link libraries, creating a recursion."); return std::string(); } -#undef TRANSITIVE_PROPERTY_COMPARE - - if (!haveProp) { - return std::string(); - } } else { #define ASSERT_TRANSITIVE_PROPERTY_METHOD(METHOD) dagCheckerParent->METHOD() || - assert(CM_FOR_EACH_TRANSITIVE_PROPERTY_METHOD( ASSERT_TRANSITIVE_PROPERTY_METHOD) false); // NOLINT(clang-tidy) #undef ASSERT_TRANSITIVE_PROPERTY_METHOD } } - std::string linkedTargetsContent; - - std::string interfacePropertyName; - bool isInterfaceProperty = false; + if (isInterfaceProperty) { + return target->EvaluateInterfaceProperty(propertyName, context, + dagCheckerParent); + } -#define POPULATE_INTERFACE_PROPERTY_NAME(prop) \ - if (propertyName == #prop) { \ - interfacePropertyName = "INTERFACE_" #prop; \ - } else if (propertyName == "INTERFACE_" #prop) { \ - interfacePropertyName = "INTERFACE_" #prop; \ - isInterfaceProperty = true; \ - } else + cmGeneratorExpressionDAGChecker dagChecker( + context->Backtrace, target, propertyName, content, dagCheckerParent); - CM_FOR_EACH_TRANSITIVE_PROPERTY_NAME(POPULATE_INTERFACE_PROPERTY_NAME) - // Note that the above macro terminates with an else - /* else */ if (cmHasLiteralPrefix(propertyName, "COMPILE_DEFINITIONS_")) { - cmPolicies::PolicyStatus polSt = - context->LG->GetPolicyStatus(cmPolicies::CMP0043); - if (polSt == cmPolicies::WARN || polSt == cmPolicies::OLD) { - interfacePropertyName = "INTERFACE_COMPILE_DEFINITIONS"; - } + switch (dagChecker.Check()) { + case cmGeneratorExpressionDAGChecker::SELF_REFERENCE: + dagChecker.ReportError(context, content->GetOriginalExpression()); + return std::string(); + case cmGeneratorExpressionDAGChecker::CYCLIC_REFERENCE: + // No error. We just skip cyclic references. + return std::string(); + case cmGeneratorExpressionDAGChecker::ALREADY_SEEN: + // We handle transitive properties above. For non-transitive + // properties we accept repeats anyway. + case cmGeneratorExpressionDAGChecker::DAG: + break; } -#undef POPULATE_INTERFACE_PROPERTY_NAME - cmGeneratorTarget const* headTarget = - context->HeadTarget && isInterfaceProperty ? context->HeadTarget - : target; - if (isInterfaceProperty) { - if (cmLinkInterfaceLibraries const* iface = - target->GetLinkInterfaceLibraries(context->Config, headTarget, - true)) { - linkedTargetsContent = - getLinkedTargetsContent(iface->Libraries, target, headTarget, - context, &dagChecker, interfacePropertyName); - } - } else if (!interfacePropertyName.empty()) { - if (cmLinkImplementationLibraries const* impl = - target->GetLinkImplementationLibraries(context->Config)) { - linkedTargetsContent = - getLinkedTargetsContent(impl->Libraries, target, target, context, - &dagChecker, interfacePropertyName); - } + std::string result; + bool haveProp = false; + if (const char* p = target->GetProperty(propertyName)) { + result = p; + haveProp = true; + } else if (evaluatingLinkLibraries) { + return std::string(); } - if (!haveProp) { - if (target->IsImported() || - target->GetType() == cmStateEnums::INTERFACE_LIBRARY) { - return linkedTargetsContent; - } + if (!haveProp && !target->IsImported() && + target->GetType() != cmStateEnums::INTERFACE_LIBRARY) { if (target->IsLinkInterfaceDependentBoolProperty(propertyName, context->Config)) { context->HadContextSensitiveCondition = true; @@ -1345,8 +1306,6 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode context->Config); return propContent ? propContent : ""; } - - return linkedTargetsContent; } if (!target->IsImported() && dagCheckerParent && @@ -1368,15 +1327,17 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode return propContent ? propContent : ""; } } + if (!interfacePropertyName.empty()) { - std::string result = this->EvaluateDependentExpression( - prop, context->LG, context, headTarget, target, &dagChecker); + result = this->EvaluateDependentExpression(result, context->LG, context, + target, target, &dagChecker); + std::string linkedTargetsContent = getLinkedTargetsContent( + target, interfacePropertyName, context, &dagChecker); if (!linkedTargetsContent.empty()) { result += (result.empty() ? "" : ";") + linkedTargetsContent; } - return result; } - return prop; + return result; } } targetPropertyNode; @@ -1456,7 +1417,7 @@ static const struct TargetObjectsNode : public cmGeneratorExpressionNode const char* imp = nullptr; std::string suffix; if (gt->Target->GetMappedConfig(context->Config, &loc, &imp, suffix)) { - cmSystemTools::ExpandListArgument(loc, objects); + cmExpandList(loc, objects); } context->HadContextSensitiveCondition = true; } else { @@ -1476,7 +1437,7 @@ static const struct TargetObjectsNode : public cmGeneratorExpressionNode } for (std::string& o : objects) { - o = obj_dir + o; + o = cmStrCat(obj_dir, o); } } @@ -1534,8 +1495,7 @@ static const struct CompileFeaturesNode : public cmGeneratorExpressionNode reportError(context, content->GetOriginalExpression(), error); return std::string(); } - cmSystemTools::ExpandListArgument(featuresKnown, - availableFeatures[lang]); + cmExpandList(featuresKnown, availableFeatures[lang]); } } @@ -1547,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) { @@ -1734,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; } }; @@ -1775,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; } }; @@ -2250,8 +2207,7 @@ static const struct ShellPathNode : public cmGeneratorExpressionNode const GeneratorExpressionContent* content, cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override { - std::vector<std::string> listIn; - cmSystemTools::ExpandListArgument(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 036a07d..3048c5f 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -7,7 +7,7 @@ #include <assert.h> #include <errno.h> #include <iterator> -#include <memory> // IWYU pragma: keep +#include <memory> #include <queue> #include <sstream> #include <stdio.h> @@ -22,7 +22,9 @@ #include "cmCustomCommandGenerator.h" #include "cmCustomCommandLines.h" #include "cmGeneratorExpression.h" +#include "cmGeneratorExpressionContext.h" #include "cmGeneratorExpressionDAGChecker.h" +#include "cmGeneratorExpressionNode.h" #include "cmGlobalGenerator.h" #include "cmLocalGenerator.h" #include "cmMakefile.h" @@ -32,10 +34,12 @@ #include "cmSourceFile.h" #include "cmSourceFileLocation.h" #include "cmState.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmTarget.h" #include "cmTargetLinkLibraryType.h" #include "cmTargetPropertyComputer.h" +#include "cm_string_view.hxx" #include "cmake.h" class cmMessenger; @@ -92,9 +96,6 @@ public: virtual bool GetHadContextSensitiveCondition() const { return false; } cmLinkImplItem const& LinkImplItem; - -private: - cmListFileBacktrace Backtrace; }; cmLinkImplItem cmGeneratorTarget::TargetPropertyEntry::NoLinkImplItem; @@ -209,6 +210,62 @@ void CreatePropertyGeneratorExpressions( } } +namespace { +// Represent a target property entry after evaluating generator expressions +// and splitting up lists. +struct EvaluatedTargetPropertyEntry +{ + EvaluatedTargetPropertyEntry(cmLinkImplItem const& item, + cmListFileBacktrace bt) + : LinkImplItem(item) + , Backtrace(std::move(bt)) + { + } + + // Move-only. + EvaluatedTargetPropertyEntry(EvaluatedTargetPropertyEntry&&) = default; + EvaluatedTargetPropertyEntry(EvaluatedTargetPropertyEntry const&) = delete; + EvaluatedTargetPropertyEntry& operator=(EvaluatedTargetPropertyEntry&&) = + delete; + EvaluatedTargetPropertyEntry& operator=( + EvaluatedTargetPropertyEntry const&) = delete; + + cmLinkImplItem const& LinkImplItem; + cmListFileBacktrace Backtrace; + std::vector<std::string> Values; + bool ContextDependent = false; +}; + +EvaluatedTargetPropertyEntry EvaluateTargetPropertyEntry( + cmGeneratorTarget const* thisTarget, std::string const& config, + std::string const& lang, cmGeneratorExpressionDAGChecker* dagChecker, + cmGeneratorTarget::TargetPropertyEntry* entry) +{ + EvaluatedTargetPropertyEntry ee(entry->LinkImplItem, entry->GetBacktrace()); + cmExpandList(entry->Evaluate(thisTarget->GetLocalGenerator(), config, false, + thisTarget, dagChecker, lang), + ee.Values); + if (entry->GetHadContextSensitiveCondition()) { + ee.ContextDependent = true; + } + return ee; +} + +std::vector<EvaluatedTargetPropertyEntry> EvaluateTargetPropertyEntries( + cmGeneratorTarget const* thisTarget, std::string const& config, + std::string const& lang, cmGeneratorExpressionDAGChecker* dagChecker, + std::vector<cmGeneratorTarget::TargetPropertyEntry*> const& in) +{ + std::vector<EvaluatedTargetPropertyEntry> out; + out.reserve(in.size()); + for (cmGeneratorTarget::TargetPropertyEntry* entry : in) { + out.emplace_back(EvaluateTargetPropertyEntry(thisTarget, config, lang, + dagChecker, entry)); + } + return out; +} +} + cmGeneratorTarget::cmGeneratorTarget(cmTarget* t, cmLocalGenerator* lg) : Target(t) , FortranModuleDirectoryCreated(false) @@ -259,9 +316,6 @@ cmGeneratorTarget::cmGeneratorTarget(cmTarget* t, cmLocalGenerator* lg) t->GetSourceBacktraces(), this->SourceEntries, true); - this->DLLPlatform = - !this->Makefile->GetSafeDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX").empty(); - this->PolicyMap = t->GetPolicyMap(); } @@ -468,12 +522,14 @@ std::string cmGeneratorTarget::GetFilePrefix( const std::string& config, cmStateEnums::ArtifactType artifact) const { if (this->IsImported()) { - const char* prefix = this->GetFilePrefixInternal(artifact); + const char* prefix = this->GetFilePrefixInternal(config, artifact); 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; } @@ -481,12 +537,14 @@ std::string cmGeneratorTarget::GetFileSuffix( const std::string& config, cmStateEnums::ArtifactType artifact) const { if (this->IsImported()) { - const char* suffix = this->GetFileSuffixInternal(artifact); + const char* suffix = this->GetFileSuffixInternal(config, artifact); 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; } @@ -495,8 +553,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 && @@ -508,7 +566,8 @@ std::string cmGeneratorTarget::GetFilePostfix(const std::string& config) const } const char* cmGeneratorTarget::GetFilePrefixInternal( - cmStateEnums::ArtifactType artifact, const std::string& language) const + std::string const& config, cmStateEnums::ArtifactType artifact, + const std::string& language) const { // no prefix for non-main target types. if (this->GetType() != cmStateEnums::STATIC_LIBRARY && @@ -523,8 +582,7 @@ const char* cmGeneratorTarget::GetFilePrefixInternal( // Return an empty prefix for the import library if this platform // does not support import libraries. - if (isImportedLibraryArtifact && - !this->Makefile->GetDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX")) { + if (isImportedLibraryArtifact && !this->NeedImportLibraryName(config)) { return nullptr; } @@ -558,7 +616,8 @@ const char* cmGeneratorTarget::GetFilePrefixInternal( return targetPrefix; } const char* cmGeneratorTarget::GetFileSuffixInternal( - cmStateEnums::ArtifactType artifact, const std::string& language) const + std::string const& config, cmStateEnums::ArtifactType artifact, + const std::string& language) const { // no suffix for non-main target types. if (this->GetType() != cmStateEnums::STATIC_LIBRARY && @@ -573,8 +632,7 @@ const char* cmGeneratorTarget::GetFileSuffixInternal( // Return an empty suffix for the import library if this platform // does not support import libraries. - if (isImportedLibraryArtifact && - !this->Makefile->GetDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX")) { + if (isImportedLibraryArtifact && !this->NeedImportLibraryName(config)) { return nullptr; } @@ -657,20 +715,21 @@ std::vector<cmSourceFile*> const* cmGeneratorTarget::GetSourceDepends( return nullptr; } -static void handleSystemIncludesDep( - cmLocalGenerator* lg, cmGeneratorTarget const* depTgt, - const std::string& config, cmGeneratorTarget const* headTarget, - cmGeneratorExpressionDAGChecker* dagChecker, - std::vector<std::string>& result, bool excludeImported, - std::string const& language) +namespace { +void handleSystemIncludesDep(cmLocalGenerator* lg, + cmGeneratorTarget const* depTgt, + const std::string& config, + cmGeneratorTarget const* headTarget, + cmGeneratorExpressionDAGChecker* dagChecker, + std::vector<std::string>& result, + bool excludeImported, std::string const& language) { if (const char* dirs = depTgt->GetProperty("INTERFACE_SYSTEM_INCLUDE_DIRECTORIES")) { cmGeneratorExpression ge; - cmSystemTools::ExpandListArgument( - ge.Parse(dirs)->Evaluate(lg, config, false, headTarget, depTgt, - dagChecker, language), - result); + cmExpandList(ge.Parse(dirs)->Evaluate(lg, config, false, headTarget, + depTgt, dagChecker, language), + result); } if (!depTgt->IsImported() || excludeImported) { return; @@ -679,12 +738,12 @@ static void handleSystemIncludesDep( if (const char* dirs = depTgt->GetProperty("INTERFACE_INCLUDE_DIRECTORIES")) { cmGeneratorExpression ge; - cmSystemTools::ExpandListArgument( - ge.Parse(dirs)->Evaluate(lg, config, false, headTarget, depTgt, - dagChecker, language), - result); + cmExpandList(ge.Parse(dirs)->Evaluate(lg, config, false, headTarget, + depTgt, dagChecker, language), + result); } } +} /* clang-format off */ #define IMPLEMENT_VISIT(KIND) \ @@ -735,9 +794,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; } @@ -771,7 +829,7 @@ bool cmGeneratorTarget::IsIPOEnabled(std::string const& lang, std::string const& config) const { const char* feature = "INTERPROCEDURAL_OPTIMIZATION"; - const bool result = cmSystemTools::IsOn(this->GetFeature(feature, config)); + const bool result = cmIsOn(this->GetFeature(feature, config)); if (!result) { // 'INTERPROCEDURAL_OPTIMIZATION' is off, no need to check policies @@ -1057,10 +1115,9 @@ bool cmGeneratorTarget::IsSystemIncludeDirectory( std::vector<std::string> result; for (std::string const& it : this->Target->GetSystemIncludeDirectories()) { cmGeneratorExpression ge; - cmSystemTools::ExpandListArgument( - ge.Parse(it)->Evaluate(this->LocalGenerator, config, false, this, - &dagChecker, language), - result); + cmExpandList(ge.Parse(it)->Evaluate(this->LocalGenerator, config, false, + this, &dagChecker, language), + result); } std::vector<cmGeneratorTarget const*> const& deps = @@ -1087,77 +1144,204 @@ bool cmGeneratorTarget::GetPropertyAsBool(const std::string& prop) const return this->Target->GetPropertyAsBool(prop); } -static void AddInterfaceEntries( - cmGeneratorTarget const* thisTarget, std::string const& config, - std::string const& prop, - std::vector<cmGeneratorTarget::TargetPropertyEntry*>& entries) +bool cmGeneratorTarget::MaybeHaveInterfaceProperty( + std::string const& prop, cmGeneratorExpressionContext* context) const +{ + std::string const key = prop + '@' + context->Config; + auto i = this->MaybeInterfacePropertyExists.find(key); + if (i == this->MaybeInterfacePropertyExists.end()) { + // Insert an entry now in case there is a cycle. + i = this->MaybeInterfacePropertyExists.emplace(key, false).first; + bool& maybeInterfaceProp = i->second; + + // If this target itself has a non-empty property value, we are done. + const char* p = this->GetProperty(prop); + maybeInterfaceProp = p && *p; + + // Otherwise, recurse to interface dependencies. + if (!maybeInterfaceProp) { + cmGeneratorTarget const* headTarget = + context->HeadTarget ? context->HeadTarget : this; + if (cmLinkInterfaceLibraries const* iface = + this->GetLinkInterfaceLibraries(context->Config, headTarget, + true)) { + if (iface->HadHeadSensitiveCondition) { + // With a different head target we may get to a library with + // this interface property. + maybeInterfaceProp = true; + } else { + // The transitive interface libraries do not depend on the + // head target, so we can follow them. + for (cmLinkItem const& lib : iface->Libraries) { + if (lib.Target && + lib.Target->MaybeHaveInterfaceProperty(prop, context)) { + maybeInterfaceProp = true; + break; + } + } + } + } + } + } + return i->second; +} + +std::string cmGeneratorTarget::EvaluateInterfaceProperty( + std::string const& prop, cmGeneratorExpressionContext* context, + cmGeneratorExpressionDAGChecker* dagCheckerParent) const +{ + std::string result; + + // If the property does not appear transitively at all, we are done. + if (!this->MaybeHaveInterfaceProperty(prop, context)) { + return result; + } + + // Evaluate $<TARGET_PROPERTY:this,prop> as if it were compiled. This is + // a subset of TargetPropertyNode::Evaluate without stringify/parse steps + // but sufficient for transitive interface properties. + cmGeneratorExpressionDAGChecker dagChecker(context->Backtrace, this, prop, + nullptr, dagCheckerParent); + switch (dagChecker.Check()) { + case cmGeneratorExpressionDAGChecker::SELF_REFERENCE: + dagChecker.ReportError( + context, "$<TARGET_PROPERTY:" + this->GetName() + "," + prop + ">"); + return result; + case cmGeneratorExpressionDAGChecker::CYCLIC_REFERENCE: + // No error. We just skip cyclic references. + return result; + case cmGeneratorExpressionDAGChecker::ALREADY_SEEN: + // No error. We have already seen this transitive property. + return result; + case cmGeneratorExpressionDAGChecker::DAG: + break; + } + + cmGeneratorTarget const* headTarget = + context->HeadTarget ? context->HeadTarget : this; + + if (const char* p = this->GetProperty(prop)) { + result = cmGeneratorExpressionNode::EvaluateDependentExpression( + p, context->LG, context, headTarget, this, &dagChecker); + } + + if (cmLinkInterfaceLibraries const* iface = + this->GetLinkInterfaceLibraries(context->Config, headTarget, true)) { + for (cmLinkItem const& lib : iface->Libraries) { + // Broken code can have a target in its own link interface. + // Don't follow such link interface entries so as not to create a + // self-referencing loop. + if (lib.Target && lib.Target != this) { + // Pretend $<TARGET_PROPERTY:lib.Target,prop> appeared in the + // above property and hand-evaluate it as if it were compiled. + // Create a context as cmCompiledGeneratorExpression::Evaluate does. + cmGeneratorExpressionContext libContext( + context->LG, context->Config, context->Quiet, headTarget, this, + context->EvaluateForBuildsystem, context->Backtrace, + context->Language); + std::string libResult = cmGeneratorExpression::StripEmptyListElements( + lib.Target->EvaluateInterfaceProperty(prop, &libContext, + &dagChecker)); + if (!libResult.empty()) { + if (result.empty()) { + result = std::move(libResult); + } else { + result.reserve(result.size() + 1 + libResult.size()); + result += ";"; + result += libResult; + } + } + context->HadContextSensitiveCondition = + context->HadContextSensitiveCondition || + libContext.HadContextSensitiveCondition; + context->HadHeadSensitiveCondition = + context->HadHeadSensitiveCondition || + libContext.HadHeadSensitiveCondition; + } + } + } + + return result; +} + +namespace { +void AddInterfaceEntries(cmGeneratorTarget const* headTarget, + std::string const& config, std::string const& prop, + std::string const& lang, + cmGeneratorExpressionDAGChecker* dagChecker, + std::vector<EvaluatedTargetPropertyEntry>& entries) { if (cmLinkImplementationLibraries const* impl = - thisTarget->GetLinkImplementationLibraries(config)) { + headTarget->GetLinkImplementationLibraries(config)) { for (cmLinkImplItem const& lib : impl->Libraries) { if (lib.Target) { - std::string uniqueName = - thisTarget->GetGlobalGenerator()->IndexGeneratorTargetUniquely( - lib.Target); - std::string genex = - "$<TARGET_PROPERTY:" + std::move(uniqueName) + "," + prop + ">"; - cmGeneratorExpression ge(lib.Backtrace); - std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(genex); - cge->SetEvaluateForBuildsystem(true); - entries.push_back(new TargetPropertyEntryGenex(std::move(cge), lib)); + EvaluatedTargetPropertyEntry ee(lib, lib.Backtrace); + // Pretend $<TARGET_PROPERTY:lib.Target,prop> appeared in our + // caller's property and hand-evaluate it as if it were compiled. + // Create a context as cmCompiledGeneratorExpression::Evaluate does. + cmGeneratorExpressionContext context( + headTarget->GetLocalGenerator(), config, false, headTarget, + headTarget, true, lib.Backtrace, lang); + cmExpandList( + lib.Target->EvaluateInterfaceProperty(prop, &context, dagChecker), + ee.Values); + ee.ContextDependent = context.HadContextSensitiveCondition; + entries.emplace_back(std::move(ee)); } } } } -static void AddObjectEntries( - cmGeneratorTarget const* thisTarget, std::string const& config, - std::vector<cmGeneratorTarget::TargetPropertyEntry*>& entries) +void AddObjectEntries(cmGeneratorTarget const* headTarget, + std::string const& config, + cmGeneratorExpressionDAGChecker* dagChecker, + std::vector<EvaluatedTargetPropertyEntry>& entries) { if (cmLinkImplementationLibraries const* impl = - thisTarget->GetLinkImplementationLibraries(config)) { + headTarget->GetLinkImplementationLibraries(config)) { for (cmLinkImplItem const& lib : impl->Libraries) { if (lib.Target && lib.Target->GetType() == cmStateEnums::OBJECT_LIBRARY) { std::string uniqueName = - thisTarget->GetGlobalGenerator()->IndexGeneratorTargetUniquely( + headTarget->GetGlobalGenerator()->IndexGeneratorTargetUniquely( lib.Target); std::string genex = "$<TARGET_OBJECTS:" + std::move(uniqueName) + ">"; cmGeneratorExpression ge(lib.Backtrace); std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(genex); cge->SetEvaluateForBuildsystem(true); - entries.push_back(new TargetPropertyEntryGenex(std::move(cge), lib)); + + EvaluatedTargetPropertyEntry ee(lib, lib.Backtrace); + cmExpandList(cge->Evaluate(headTarget->GetLocalGenerator(), config, + false, headTarget, dagChecker), + ee.Values); + if (cge->GetHadContextSensitiveCondition()) { + ee.ContextDependent = true; + } + entries.emplace_back(std::move(ee)); } } } } -static bool processSources( - cmGeneratorTarget const* tgt, - const std::vector<cmGeneratorTarget::TargetPropertyEntry*>& entries, - std::vector<BT<std::string>>& srcs, - std::unordered_set<std::string>& uniqueSrcs, - cmGeneratorExpressionDAGChecker* dagChecker, std::string const& config, - bool debugSources) +bool processSources(cmGeneratorTarget const* tgt, + std::vector<EvaluatedTargetPropertyEntry>& entries, + std::vector<BT<std::string>>& srcs, + std::unordered_set<std::string>& uniqueSrcs, + bool debugSources) { cmMakefile* mf = tgt->Target->GetMakefile(); bool contextDependent = false; - for (cmGeneratorTarget::TargetPropertyEntry* entry : entries) { - cmLinkImplItem const& item = entry->LinkImplItem; - std::string const& targetName = item.AsStr(); - std::vector<std::string> entrySources; - cmSystemTools::ExpandListArgument(entry->Evaluate(tgt->GetLocalGenerator(), - config, false, tgt, tgt, - dagChecker), - entrySources); - - if (entry->GetHadContextSensitiveCondition()) { + for (EvaluatedTargetPropertyEntry& entry : entries) { + if (entry.ContextDependent) { contextDependent = true; } - for (std::string& src : entrySources) { + cmLinkImplItem const& item = entry.LinkImplItem; + std::string const& targetName = item.AsStr(); + + for (std::string& src : entry.Values) { cmSourceFile* sf = mf->GetOrCreateSource(src); std::string e; std::string fullPath = sf->GetFullPath(&e); @@ -1186,9 +1370,9 @@ static bool processSources( src = fullPath; } std::string usedSources; - for (std::string const& src : entrySources) { + for (std::string const& src : entry.Values) { if (uniqueSrcs.insert(src).second) { - srcs.emplace_back(src, entry->GetBacktrace()); + srcs.emplace_back(src, entry.Backtrace); if (debugSources) { usedSources += " * " + src + "\n"; } @@ -1199,11 +1383,12 @@ static bool processSources( MessageType::LOG, std::string("Used sources for target ") + tgt->GetName() + ":\n" + usedSources, - entry->GetBacktrace()); + entry.Backtrace); } } return contextDependent; } +} std::vector<BT<std::string>> cmGeneratorTarget::GetSourceFilePaths( std::string const& config) const @@ -1220,8 +1405,7 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetSourceFilePaths( cmStringRange sourceEntries = this->Target->GetSourceEntries(); for (std::string const& entry : sourceEntries) { - std::vector<std::string> items; - cmSystemTools::ExpandListArgument(entry, items); + std::vector<std::string> items = cmExpandedList(entry); for (std::string const& item : items) { if (cmHasLiteralPrefix(item, "$<TARGET_OBJECTS:") && item.back() == '>') { @@ -1237,12 +1421,11 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetSourceFilePaths( const char* debugProp = this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES"); if (debugProp) { - cmSystemTools::ExpandListArgument(debugProp, debugProperties); + 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; @@ -1251,28 +1434,28 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetSourceFilePaths( cmGeneratorExpressionDAGChecker dagChecker(this, "SOURCES", nullptr, nullptr); + std::vector<EvaluatedTargetPropertyEntry> entries = + EvaluateTargetPropertyEntries(this, config, std::string(), &dagChecker, + this->SourceEntries); + std::unordered_set<std::string> uniqueSrcs; bool contextDependentDirectSources = - processSources(this, this->SourceEntries, files, uniqueSrcs, &dagChecker, - config, debugSources); + processSources(this, entries, files, uniqueSrcs, debugSources); // Collect INTERFACE_SOURCES of all direct link-dependencies. - std::vector<cmGeneratorTarget::TargetPropertyEntry*> - linkInterfaceSourcesEntries; - AddInterfaceEntries(this, config, "INTERFACE_SOURCES", - linkInterfaceSourcesEntries); + std::vector<EvaluatedTargetPropertyEntry> linkInterfaceSourcesEntries; + AddInterfaceEntries(this, config, "INTERFACE_SOURCES", std::string(), + &dagChecker, linkInterfaceSourcesEntries); std::vector<std::string>::size_type numFilesBefore = files.size(); - bool contextDependentInterfaceSources = - processSources(this, linkInterfaceSourcesEntries, files, uniqueSrcs, - &dagChecker, config, debugSources); + bool contextDependentInterfaceSources = processSources( + this, linkInterfaceSourcesEntries, files, uniqueSrcs, debugSources); // Collect TARGET_OBJECTS of direct object link-dependencies. - std::vector<cmGeneratorTarget::TargetPropertyEntry*> linkObjectsEntries; - AddObjectEntries(this, config, linkObjectsEntries); + std::vector<EvaluatedTargetPropertyEntry> linkObjectsEntries; + AddObjectEntries(this, config, &dagChecker, linkObjectsEntries); std::vector<std::string>::size_type numFilesBefore2 = files.size(); bool contextDependentObjects = - processSources(this, linkObjectsEntries, files, uniqueSrcs, &dagChecker, - config, debugSources); + processSources(this, linkObjectsEntries, files, uniqueSrcs, debugSources); if (!contextDependentDirectSources && !(contextDependentInterfaceSources && numFilesBefore < files.size()) && @@ -1280,8 +1463,6 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetSourceFilePaths( this->LinkImplementationLanguageIsContextDependent = false; } - cmDeleteAll(linkInterfaceSourcesEntries); - cmDeleteAll(linkObjectsEntries); return files; } @@ -1521,8 +1702,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"; @@ -1594,9 +1774,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. @@ -1612,7 +1791,7 @@ bool cmGeneratorTarget::NeedRelinkBeforeInstall( // will likely change between the build tree and install tree and // this target must be relinked. bool have_rpath = - this->HaveBuildTreeRPATH(config) || this->HaveInstallTreeRPATH(); + this->HaveBuildTreeRPATH(config) || this->HaveInstallTreeRPATH(config); bool is_ninja = this->LocalGenerator->GetGlobalGenerator()->GetName() == "Ninja"; @@ -1674,9 +1853,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 @@ -1793,7 +1971,7 @@ bool cmGeneratorTarget::MacOSXUseInstallNameDir() const const char* build_with_install_name = this->GetProperty("BUILD_WITH_INSTALL_NAME_DIR"); if (build_with_install_name) { - return cmSystemTools::IsOn(build_with_install_name); + return cmIsOn(build_with_install_name); } cmPolicies::PolicyStatus cmp0068 = this->GetPolicyStatusCMP0068(); @@ -1858,23 +2036,23 @@ std::string cmGeneratorTarget::GetSOName(const std::string& config) const return this->GetLibraryNames(config).SharedObject; } -static bool shouldAddFullLevel(cmGeneratorTarget::BundleDirectoryLevel level) +namespace { +bool shouldAddFullLevel(cmGeneratorTarget::BundleDirectoryLevel level) { return level == cmGeneratorTarget::FullLevel; } -static bool shouldAddContentLevel( - cmGeneratorTarget::BundleDirectoryLevel level) +bool shouldAddContentLevel(cmGeneratorTarget::BundleDirectoryLevel level) { return level == cmGeneratorTarget::ContentLevel || shouldAddFullLevel(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"; @@ -1899,9 +2077,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()) { @@ -1924,9 +2101,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"; @@ -1983,8 +2159,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) { @@ -2025,8 +2200,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; @@ -2247,8 +2421,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 @@ -2284,10 +2457,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; } @@ -2341,7 +2513,7 @@ void cmGeneratorTarget::ComputeModuleDefinitionInfo( info.WindowsExportAllSymbols = this->Makefile->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS") && this->GetPropertyAsBool("WINDOWS_EXPORT_ALL_SYMBOLS"); -#if defined(_WIN32) && defined(CMAKE_BUILD_WITH_CMAKE) +#if defined(_WIN32) && !defined(CMAKE_BOOTSTRAP) info.DefFileGenerated = info.WindowsExportAllSymbols || info.Sources.size() > 1; #else @@ -2357,7 +2529,7 @@ void cmGeneratorTarget::ComputeModuleDefinitionInfo( bool cmGeneratorTarget::IsDLLPlatform() const { - return this->DLLPlatform; + return this->Target->IsDLLPlatform(); } void cmGeneratorTarget::GetAutoUicOptions(std::vector<std::string>& result, @@ -2372,10 +2544,9 @@ void cmGeneratorTarget::GetAutoUicOptions(std::vector<std::string>& result, cmGeneratorExpressionDAGChecker dagChecker(this, "AUTOUIC_OPTIONS", nullptr, nullptr); - cmSystemTools::ExpandListArgument( - ge.Parse(prop)->Evaluate(this->LocalGenerator, config, false, this, - &dagChecker), - result); + cmExpandList(ge.Parse(prop)->Evaluate(this->LocalGenerator, config, false, + this, &dagChecker), + result); } void processILibs(const std::string& config, @@ -2468,7 +2639,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 " @@ -2502,8 +2673,7 @@ void cmTargetTraceDependencies::Trace() // Queue dependencies added explicitly by the user. if (const char* additionalDeps = sf->GetProperty("OBJECT_DEPENDS")) { - std::vector<std::string> objDeps; - cmSystemTools::ExpandListArgument(additionalDeps, objDeps); + std::vector<std::string> objDeps = cmExpandedList(additionalDeps); for (std::string& objDep : objDeps) { if (cmSystemTools::FileIsFullPath(objDep)) { objDep = cmSystemTools::CollapseFullPath(objDep); @@ -2716,15 +2886,15 @@ 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) { archs = this->GetProperty("OSX_ARCHITECTURES"); } if (archs) { - cmSystemTools::ExpandListArgument(std::string(archs), archVec); + cmExpandList(std::string(archs), archVec); } } @@ -2757,33 +2927,35 @@ std::string cmGeneratorTarget::GetCreateRuleVariable( case cmStateEnums::MODULE_LIBRARY: return "CMAKE_" + lang + "_CREATE_SHARED_MODULE"; case cmStateEnums::EXECUTABLE: + if (this->IsExecutableWithExports()) { + std::string linkExeWithExports = + "CMAKE_" + lang + "_LINK_EXECUTABLE_WITH_EXPORTS"; + if (this->Makefile->IsDefinitionSet(linkExeWithExports)) { + return linkExeWithExports; + } + } return "CMAKE_" + lang + "_LINK_EXECUTABLE"; default: break; } return ""; } -static void processIncludeDirectories( + +namespace { +void processIncludeDirectories( cmGeneratorTarget const* tgt, - const std::vector<cmGeneratorTarget::TargetPropertyEntry*>& entries, + std::vector<EvaluatedTargetPropertyEntry>& entries, std::vector<BT<std::string>>& includes, - std::unordered_set<std::string>& uniqueIncludes, - cmGeneratorExpressionDAGChecker* dagChecker, const std::string& config, - bool debugIncludes, const std::string& language) + std::unordered_set<std::string>& uniqueIncludes, bool debugIncludes) { - for (cmGeneratorTarget::TargetPropertyEntry* entry : entries) { - cmLinkImplItem const& item = entry->LinkImplItem; + for (EvaluatedTargetPropertyEntry& entry : entries) { + cmLinkImplItem const& item = entry.LinkImplItem; std::string const& targetName = item.AsStr(); bool const fromImported = item.Target && item.Target->IsImported(); bool const checkCMP0027 = item.FromGenex; - std::vector<std::string> entryIncludes; - cmSystemTools::ExpandListArgument(entry->Evaluate(tgt->GetLocalGenerator(), - config, false, tgt, - dagChecker, language), - entryIncludes); std::string usedIncludes; - for (std::string& entryInclude : entryIncludes) { + for (std::string& entryInclude : entry.Values) { if (fromImported && !cmSystemTools::FileExists(entryInclude)) { std::ostringstream e; MessageType messageType = MessageType::FATAL_ERROR; @@ -2852,15 +3024,14 @@ static void processIncludeDirectories( } } - if (!cmSystemTools::IsOff(entryInclude)) { + if (!cmIsOff(entryInclude)) { cmSystemTools::ConvertToUnixSlashes(entryInclude); } - std::string inc = entryInclude; - if (uniqueIncludes.insert(inc).second) { - includes.emplace_back(inc, entry->GetBacktrace()); + if (uniqueIncludes.insert(entryInclude).second) { + includes.emplace_back(entryInclude, entry.Backtrace); if (debugIncludes) { - usedIncludes += " * " + inc + "\n"; + usedIncludes += " * " + entryInclude + "\n"; } } } @@ -2869,10 +3040,11 @@ static void processIncludeDirectories( MessageType::LOG, std::string("Used includes for target ") + tgt->GetName() + ":\n" + usedIncludes, - entry->GetBacktrace()); + entry.Backtrace); } } } +} std::vector<BT<std::string>> cmGeneratorTarget::GetIncludeDirectories( const std::string& config, const std::string& lang) const @@ -2887,25 +3059,22 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetIncludeDirectories( const char* debugProp = this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES"); if (debugProp) { - cmSystemTools::ExpandListArgument(debugProp, debugProperties); + cmExpandList(debugProp, debugProperties); } 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; } - processIncludeDirectories(this, this->IncludeDirectoriesEntries, includes, - uniqueIncludes, &dagChecker, config, debugIncludes, - lang); + std::vector<EvaluatedTargetPropertyEntry> entries = + EvaluateTargetPropertyEntries(this, config, lang, &dagChecker, + this->IncludeDirectoriesEntries); - std::vector<cmGeneratorTarget::TargetPropertyEntry*> - linkInterfaceIncludeDirectoriesEntries; - AddInterfaceEntries(this, config, "INTERFACE_INCLUDE_DIRECTORIES", - linkInterfaceIncludeDirectoriesEntries); + AddInterfaceEntries(this, config, "INTERFACE_INCLUDE_DIRECTORIES", lang, + &dagChecker, entries); if (this->Makefile->IsOn("APPLE")) { cmLinkImplementationLibraries const* impl = @@ -2921,16 +3090,14 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetIncludeDirectories( libDir = frameworkCheck.match(1); - linkInterfaceIncludeDirectoriesEntries.push_back( - CreateTargetPropertyEntry(libDir)); + EvaluatedTargetPropertyEntry ee(lib, cmListFileBacktrace()); + ee.Values.emplace_back(std::move(libDir)); + entries.emplace_back(std::move(ee)); } } - processIncludeDirectories(this, linkInterfaceIncludeDirectoriesEntries, - includes, uniqueIncludes, &dagChecker, config, - debugIncludes, lang); - - cmDeleteAll(linkInterfaceIncludeDirectoriesEntries); + processIncludeDirectories(this, entries, includes, uniqueIncludes, + debugIncludes); return includes; } @@ -2941,33 +3108,26 @@ enum class OptionsParse Shell }; -static void processOptionsInternal( - cmGeneratorTarget const* tgt, - const std::vector<cmGeneratorTarget::TargetPropertyEntry*>& entries, - std::vector<BT<std::string>>& options, - std::unordered_set<std::string>& uniqueOptions, - cmGeneratorExpressionDAGChecker* dagChecker, const std::string& config, - bool debugOptions, const char* logName, std::string const& language, - OptionsParse parse) -{ - for (cmGeneratorTarget::TargetPropertyEntry* entry : entries) { - std::vector<std::string> entryOptions; - cmSystemTools::ExpandListArgument(entry->Evaluate(tgt->GetLocalGenerator(), - config, false, tgt, - dagChecker, language), - entryOptions); +namespace { +void processOptions(cmGeneratorTarget const* tgt, + std::vector<EvaluatedTargetPropertyEntry> const& entries, + std::vector<BT<std::string>>& options, + std::unordered_set<std::string>& uniqueOptions, + bool debugOptions, const char* logName, OptionsParse parse) +{ + for (EvaluatedTargetPropertyEntry const& entry : entries) { std::string usedOptions; - for (std::string const& opt : entryOptions) { + for (std::string const& opt : entry.Values) { if (uniqueOptions.insert(opt).second) { if (parse == OptionsParse::Shell && cmHasLiteralPrefix(opt, "SHELL:")) { std::vector<std::string> tmp; cmSystemTools::ParseUnixCommandLine(opt.c_str() + 6, tmp); for (std::string& o : tmp) { - options.emplace_back(std::move(o), entry->GetBacktrace()); + options.emplace_back(std::move(o), entry.Backtrace); } } else { - options.emplace_back(opt, entry->GetBacktrace()); + options.emplace_back(opt, entry.Backtrace); } if (debugOptions) { usedOptions += " * " + opt + "\n"; @@ -2979,22 +3139,10 @@ static void processOptionsInternal( MessageType::LOG, std::string("Used ") + logName + std::string(" for target ") + tgt->GetName() + ":\n" + usedOptions, - entry->GetBacktrace()); + entry.Backtrace); } } } - -static void processCompileOptions( - cmGeneratorTarget const* tgt, - const std::vector<cmGeneratorTarget::TargetPropertyEntry*>& entries, - std::vector<BT<std::string>>& options, - std::unordered_set<std::string>& uniqueOptions, - cmGeneratorExpressionDAGChecker* dagChecker, const std::string& config, - bool debugOptions, std::string const& language) -{ - processOptionsInternal(tgt, entries, options, uniqueOptions, dagChecker, - config, debugOptions, "compile options", language, - OptionsParse::Shell); } void cmGeneratorTarget::GetCompileOptions(std::vector<std::string>& result, @@ -3021,48 +3169,29 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetCompileOptions( const char* debugProp = this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES"); if (debugProp) { - cmSystemTools::ExpandListArgument(debugProp, debugProperties); + cmExpandList(debugProp, debugProperties); } 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; } - processCompileOptions(this, this->CompileOptionsEntries, result, - uniqueOptions, &dagChecker, config, debugOptions, - language); - - std::vector<cmGeneratorTarget::TargetPropertyEntry*> - linkInterfaceCompileOptionsEntries; + std::vector<EvaluatedTargetPropertyEntry> entries = + EvaluateTargetPropertyEntries(this, config, language, &dagChecker, + this->CompileOptionsEntries); - AddInterfaceEntries(this, config, "INTERFACE_COMPILE_OPTIONS", - linkInterfaceCompileOptionsEntries); + AddInterfaceEntries(this, config, "INTERFACE_COMPILE_OPTIONS", language, + &dagChecker, entries); - processCompileOptions(this, linkInterfaceCompileOptionsEntries, result, - uniqueOptions, &dagChecker, config, debugOptions, - language); + processOptions(this, entries, result, uniqueOptions, debugOptions, + "compile options", OptionsParse::Shell); - cmDeleteAll(linkInterfaceCompileOptionsEntries); return result; } -static void processCompileFeatures( - cmGeneratorTarget const* tgt, - const std::vector<cmGeneratorTarget::TargetPropertyEntry*>& entries, - std::vector<BT<std::string>>& options, - std::unordered_set<std::string>& uniqueOptions, - cmGeneratorExpressionDAGChecker* dagChecker, const std::string& config, - bool debugOptions) -{ - processOptionsInternal(tgt, entries, options, uniqueOptions, dagChecker, - config, debugOptions, "compile features", - std::string(), OptionsParse::None); -} - void cmGeneratorTarget::GetCompileFeatures(std::vector<std::string>& result, const std::string& config) const { @@ -3086,45 +3215,29 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetCompileFeatures( const char* debugProp = this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES"); if (debugProp) { - cmSystemTools::ExpandListArgument(debugProp, debugProperties); + cmExpandList(debugProp, debugProperties); } 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; } - processCompileFeatures(this, this->CompileFeaturesEntries, result, - uniqueFeatures, &dagChecker, config, debugFeatures); + std::vector<EvaluatedTargetPropertyEntry> entries = + EvaluateTargetPropertyEntries(this, config, std::string(), &dagChecker, + this->CompileFeaturesEntries); - std::vector<cmGeneratorTarget::TargetPropertyEntry*> - linkInterfaceCompileFeaturesEntries; AddInterfaceEntries(this, config, "INTERFACE_COMPILE_FEATURES", - linkInterfaceCompileFeaturesEntries); + std::string(), &dagChecker, entries); - processCompileFeatures(this, linkInterfaceCompileFeaturesEntries, result, - uniqueFeatures, &dagChecker, config, debugFeatures); + processOptions(this, entries, result, uniqueFeatures, debugFeatures, + "compile features", OptionsParse::None); - cmDeleteAll(linkInterfaceCompileFeaturesEntries); return result; } -static void processCompileDefinitions( - cmGeneratorTarget const* tgt, - const std::vector<cmGeneratorTarget::TargetPropertyEntry*>& entries, - std::vector<BT<std::string>>& options, - std::unordered_set<std::string>& uniqueOptions, - cmGeneratorExpressionDAGChecker* dagChecker, const std::string& config, - bool debugOptions, std::string const& language) -{ - processOptionsInternal(tgt, entries, options, uniqueOptions, dagChecker, - config, debugOptions, "compile definitions", language, - OptionsParse::None); -} - void cmGeneratorTarget::GetCompileDefinitions( std::vector<std::string>& result, const std::string& config, const std::string& language) const @@ -3150,25 +3263,23 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetCompileDefinitions( const char* debugProp = this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES"); if (debugProp) { - cmSystemTools::ExpandListArgument(debugProp, debugProperties); + cmExpandList(debugProp, debugProperties); } 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; } - processCompileDefinitions(this, this->CompileDefinitionsEntries, list, - uniqueOptions, &dagChecker, config, debugDefines, - language); + std::vector<EvaluatedTargetPropertyEntry> entries = + EvaluateTargetPropertyEntries(this, config, language, &dagChecker, + this->CompileDefinitionsEntries); + + AddInterfaceEntries(this, config, "INTERFACE_COMPILE_DEFINITIONS", language, + &dagChecker, entries); - std::vector<cmGeneratorTarget::TargetPropertyEntry*> - linkInterfaceCompileDefinitionsEntries; - AddInterfaceEntries(this, config, "INTERFACE_COMPILE_DEFINITIONS", - linkInterfaceCompileDefinitionsEntries); if (!config.empty()) { std::string configPropName = "COMPILE_DEFINITIONS_" + cmSystemTools::UpperCase(config); @@ -3176,15 +3287,16 @@ 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: { - linkInterfaceCompileDefinitionsEntries.push_back( + std::unique_ptr<TargetPropertyEntry> entry( CreateTargetPropertyEntry(configProp)); + entries.emplace_back(EvaluateTargetPropertyEntry( + this, config, language, &dagChecker, entry.get())); } break; case cmPolicies::NEW: case cmPolicies::REQUIRED_ALWAYS: @@ -3194,29 +3306,12 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetCompileDefinitions( } } - processCompileDefinitions(this, linkInterfaceCompileDefinitionsEntries, list, - uniqueOptions, &dagChecker, config, debugDefines, - language); + processOptions(this, entries, list, uniqueOptions, debugDefines, + "compile definitions", OptionsParse::None); - cmDeleteAll(linkInterfaceCompileDefinitionsEntries); return list; } -namespace { -void processLinkOptions( - cmGeneratorTarget const* tgt, - const std::vector<cmGeneratorTarget::TargetPropertyEntry*>& entries, - std::vector<BT<std::string>>& options, - std::unordered_set<std::string>& uniqueOptions, - cmGeneratorExpressionDAGChecker* dagChecker, const std::string& config, - bool debugOptions, std::string const& language) -{ - processOptionsInternal(tgt, entries, options, uniqueOptions, dagChecker, - config, debugOptions, "link options", language, - OptionsParse::Shell); -} -} - void cmGeneratorTarget::GetLinkOptions(std::vector<std::string>& result, const std::string& config, const std::string& language) const @@ -3241,38 +3336,31 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetLinkOptions( const char* debugProp = this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES"); if (debugProp) { - cmSystemTools::ExpandListArgument(debugProp, debugProperties); + 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; } - processLinkOptions(this, this->LinkOptionsEntries, result, uniqueOptions, - &dagChecker, config, debugOptions, language); - - std::vector<cmGeneratorTarget::TargetPropertyEntry*> - linkInterfaceLinkOptionsEntries; - - AddInterfaceEntries(this, config, "INTERFACE_LINK_OPTIONS", - linkInterfaceLinkOptionsEntries); + std::vector<EvaluatedTargetPropertyEntry> entries = + EvaluateTargetPropertyEntries(this, config, language, &dagChecker, + this->LinkOptionsEntries); - processLinkOptions(this, linkInterfaceLinkOptionsEntries, result, - uniqueOptions, &dagChecker, config, debugOptions, - language); + AddInterfaceEntries(this, config, "INTERFACE_LINK_OPTIONS", language, + &dagChecker, entries); - cmDeleteAll(linkInterfaceLinkOptionsEntries); + processOptions(this, entries, result, uniqueOptions, debugOptions, + "link options", OptionsParse::Shell); // Last step: replace "LINKER:" prefixed elements by // actual linker wrapper const std::string wrapper(this->Makefile->GetSafeDefinition( "CMAKE_" + language + "_LINKER_WRAPPER_FLAG")); - std::vector<std::string> wrapperFlag; - cmSystemTools::ExpandListArgument(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; @@ -3300,8 +3388,7 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetLinkOptions( cmSystemTools::ParseUnixCommandLine( value.c_str() + LINKER_SHELL.length(), linkerOptions); } else { - linkerOptions = - cmSystemTools::tokenize(value.substr(LINKER.length()), ","); + linkerOptions = cmTokenize(value.substr(LINKER.length()), ","); } if (linkerOptions.empty() || @@ -3371,21 +3458,6 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetLinkOptions( return result; } -namespace { -void processStaticLibraryLinkOptions( - cmGeneratorTarget const* tgt, - const std::vector<cmGeneratorTarget::TargetPropertyEntry*>& entries, - std::vector<BT<std::string>>& options, - std::unordered_set<std::string>& uniqueOptions, - cmGeneratorExpressionDAGChecker* dagChecker, const std::string& config, - std::string const& language) -{ - processOptionsInternal(tgt, entries, options, uniqueOptions, dagChecker, - config, false, "static library link options", - language, OptionsParse::Shell); -} -} - void cmGeneratorTarget::GetStaticLibraryLinkOptions( std::vector<std::string>& result, const std::string& config, const std::string& language) const @@ -3402,47 +3474,40 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetStaticLibraryLinkOptions( std::string const& config, std::string const& language) const { std::vector<BT<std::string>> result; - std::vector<cmGeneratorTarget::TargetPropertyEntry*> entries; std::unordered_set<std::string> uniqueOptions; cmGeneratorExpressionDAGChecker dagChecker(this, "STATIC_LIBRARY_OPTIONS", nullptr, nullptr); + std::vector<EvaluatedTargetPropertyEntry> entries; if (const char* linkOptions = this->GetProperty("STATIC_LIBRARY_OPTIONS")) { - std::vector<std::string> options; - cmSystemTools::ExpandListArgument(linkOptions, options); + std::vector<std::string> options = cmExpandedList(linkOptions); for (const auto& option : options) { - entries.push_back(CreateTargetPropertyEntry(option)); + std::unique_ptr<TargetPropertyEntry> entry( + CreateTargetPropertyEntry(option)); + entries.emplace_back(EvaluateTargetPropertyEntry( + this, config, language, &dagChecker, entry.get())); } } - processStaticLibraryLinkOptions(this, entries, result, uniqueOptions, - &dagChecker, config, language); + processOptions(this, entries, result, uniqueOptions, false, + "static library link options", OptionsParse::Shell); - cmDeleteAll(entries); return result; } namespace { -void processLinkDirectories( - cmGeneratorTarget const* tgt, - const std::vector<cmGeneratorTarget::TargetPropertyEntry*>& entries, - std::vector<BT<std::string>>& directories, - std::unordered_set<std::string>& uniqueDirectories, - cmGeneratorExpressionDAGChecker* dagChecker, const std::string& config, - bool debugDirectories, std::string const& language) -{ - for (cmGeneratorTarget::TargetPropertyEntry* entry : entries) { - cmLinkImplItem const& item = entry->LinkImplItem; +void processLinkDirectories(cmGeneratorTarget const* tgt, + std::vector<EvaluatedTargetPropertyEntry>& entries, + std::vector<BT<std::string>>& directories, + std::unordered_set<std::string>& uniqueDirectories, + bool debugDirectories) +{ + for (EvaluatedTargetPropertyEntry& entry : entries) { + cmLinkImplItem const& item = entry.LinkImplItem; std::string const& targetName = item.AsStr(); - std::vector<std::string> entryDirectories; - cmSystemTools::ExpandListArgument(entry->Evaluate(tgt->GetLocalGenerator(), - config, false, tgt, - dagChecker, language), - entryDirectories); - std::string usedDirectories; - for (std::string& entryDirectory : entryDirectories) { + for (std::string& entryDirectory : entry.Values) { if (!cmSystemTools::FileIsFullPath(entryDirectory)) { std::ostringstream e; bool noMessage = false; @@ -3495,7 +3560,7 @@ void processLinkDirectories( MessageType::LOG, std::string("Used link directories for target ") + tgt->GetName() + ":\n" + usedDirectories, - entry->GetBacktrace()); + entry.Backtrace); } } } @@ -3526,50 +3591,29 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetLinkDirectories( const char* debugProp = this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES"); if (debugProp) { - cmSystemTools::ExpandListArgument(debugProp, debugProperties); + cmExpandList(debugProp, debugProperties); } 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; } - processLinkDirectories(this, this->LinkDirectoriesEntries, result, - uniqueDirectories, &dagChecker, config, - debugDirectories, language); - - std::vector<cmGeneratorTarget::TargetPropertyEntry*> - linkInterfaceLinkDirectoriesEntries; + std::vector<EvaluatedTargetPropertyEntry> entries = + EvaluateTargetPropertyEntries(this, config, language, &dagChecker, + this->LinkDirectoriesEntries); - AddInterfaceEntries(this, config, "INTERFACE_LINK_DIRECTORIES", - linkInterfaceLinkDirectoriesEntries); + AddInterfaceEntries(this, config, "INTERFACE_LINK_DIRECTORIES", language, + &dagChecker, entries); - processLinkDirectories(this, linkInterfaceLinkDirectoriesEntries, result, - uniqueDirectories, &dagChecker, config, - debugDirectories, language); + processLinkDirectories(this, entries, result, uniqueDirectories, + debugDirectories); - cmDeleteAll(linkInterfaceLinkDirectoriesEntries); return result; } -namespace { -void processLinkDepends( - cmGeneratorTarget const* tgt, - const std::vector<cmGeneratorTarget::TargetPropertyEntry*>& entries, - std::vector<BT<std::string>>& options, - std::unordered_set<std::string>& uniqueOptions, - cmGeneratorExpressionDAGChecker* dagChecker, const std::string& config, - std::string const& language) -{ - processOptionsInternal(tgt, entries, options, uniqueOptions, dagChecker, - config, false, "link depends", language, - OptionsParse::None); -} -} - void cmGeneratorTarget::GetLinkDepends(std::vector<std::string>& result, const std::string& config, const std::string& language) const @@ -3585,24 +3629,26 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetLinkDepends( std::string const& config, std::string const& language) const { std::vector<BT<std::string>> result; - std::vector<cmGeneratorTarget::TargetPropertyEntry*> linkDependsEntries; std::unordered_set<std::string> uniqueOptions; cmGeneratorExpressionDAGChecker dagChecker(this, "LINK_DEPENDS", nullptr, nullptr); + std::vector<EvaluatedTargetPropertyEntry> entries; if (const char* linkDepends = this->GetProperty("LINK_DEPENDS")) { - std::vector<std::string> depends; - cmSystemTools::ExpandListArgument(linkDepends, depends); + std::vector<std::string> depends = cmExpandedList(linkDepends); for (const auto& depend : depends) { - linkDependsEntries.push_back(CreateTargetPropertyEntry(depend)); + std::unique_ptr<TargetPropertyEntry> entry( + CreateTargetPropertyEntry(depend)); + entries.emplace_back(EvaluateTargetPropertyEntry( + this, config, language, &dagChecker, entry.get())); } } - AddInterfaceEntries(this, config, "INTERFACE_LINK_DEPENDS", - linkDependsEntries); - processLinkDepends(this, linkDependsEntries, result, uniqueOptions, - &dagChecker, config, language); + AddInterfaceEntries(this, config, "INTERFACE_LINK_DEPENDS", language, + &dagChecker, entries); + + processOptions(this, entries, result, uniqueOptions, false, "link depends", + OptionsParse::None); - cmDeleteAll(linkDependsEntries); return result; } @@ -3632,33 +3678,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); } } @@ -3698,11 +3736,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. @@ -3729,8 +3766,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); } @@ -3751,8 +3788,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); } @@ -3828,8 +3865,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); } @@ -3924,8 +3961,7 @@ void cmGeneratorTarget::GetFullNameInternal( // Return an empty name for the import library if this platform // does not support import libraries. - if (isImportedLibraryArtifact && - !this->Makefile->GetDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX")) { + if (isImportedLibraryArtifact && !this->NeedImportLibraryName(config)) { outPrefix.clear(); outBase.clear(); outSuffix.clear(); @@ -3934,8 +3970,8 @@ void cmGeneratorTarget::GetFullNameInternal( // retrieve prefix and suffix std::string ll = this->GetLinkerLanguage(config); - const char* targetPrefix = this->GetFilePrefixInternal(artifact, ll); - const char* targetSuffix = this->GetFileSuffixInternal(artifact, ll); + const char* targetPrefix = this->GetFilePrefixInternal(config, artifact, ll); + const char* targetSuffix = this->GetFileSuffixInternal(config, artifact, ll); // The implib option is only allowed for shared libraries, module // libraries, and executables. @@ -3951,15 +3987,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; } @@ -4121,7 +4156,7 @@ cmGeneratorTarget::GetTargetSourceFileFlags(const cmSourceFile* sf) const if (stripResources) { flags.MacFolder = ""; } - } else if (cmSystemTools::StringStartsWith(location, "Resources/")) { + } else if (cmHasLiteralPrefix(location, "Resources/")) { flags.Type = cmGeneratorTarget::SourceFileTypeDeepResource; if (stripResources) { flags.MacFolder += strlen("Resources/"); @@ -4143,8 +4178,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; - cmSystemTools::ExpandListArgument(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]; @@ -4157,8 +4191,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; - cmSystemTools::ExpandListArgument(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]; @@ -4170,8 +4203,7 @@ void cmGeneratorTarget::ConstructSourceFileFlags() const // Mark sources listed as resources. if (const char* files = this->GetProperty("RESOURCE")) { - std::vector<std::string> relFiles; - cmSystemTools::ExpandListArgument(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]; @@ -4200,7 +4232,7 @@ cmGeneratorTarget::GetCompatibleInterfaces(std::string const& config) const #define CM_READ_COMPATIBLE_INTERFACE(X, x) \ if (const char* prop = li->GetProperty("COMPATIBLE_INTERFACE_" #X)) { \ std::vector<std::string> props; \ - cmSystemTools::ExpandListArgument(prop, props); \ + cmExpandList(prop, props); \ compat.Props##x.insert(props.begin(), props.end()); \ } CM_READ_COMPATIBLE_INTERFACE(BOOL, Bool) @@ -4313,10 +4345,9 @@ void checkPropertyConsistency(cmGeneratorTarget const* depender, return; } - std::vector<std::string> props; - cmSystemTools::ExpandListArgument(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); @@ -4343,8 +4374,9 @@ void checkPropertyConsistency(cmGeneratorTarget const* depender, } } -static std::string intersect(const std::set<std::string>& s1, - const std::set<std::string>& s2) +namespace { +std::string intersect(const std::set<std::string>& s1, + const std::set<std::string>& s2) { std::set<std::string> intersect; std::set_intersection(s1.begin(), s1.end(), s2.begin(), s2.end(), @@ -4355,9 +4387,9 @@ static std::string intersect(const std::set<std::string>& s1, return ""; } -static std::string intersect(const std::set<std::string>& s1, - const std::set<std::string>& s2, - const std::set<std::string>& s3) +std::string intersect(const std::set<std::string>& s1, + const std::set<std::string>& s2, + const std::set<std::string>& s3) { std::string result; result = intersect(s1, s2); @@ -4371,10 +4403,10 @@ static std::string intersect(const std::set<std::string>& s1, return intersect(s2, s3); } -static std::string intersect(const std::set<std::string>& s1, - const std::set<std::string>& s2, - const std::set<std::string>& s3, - const std::set<std::string>& s4) +std::string intersect(const std::set<std::string>& s1, + const std::set<std::string>& s2, + const std::set<std::string>& s3, + const std::set<std::string>& s4) { std::string result; result = intersect(s1, s2); @@ -4391,6 +4423,7 @@ static std::string intersect(const std::set<std::string>& s1, } return intersect(s2, s3, s4); } +} void cmGeneratorTarget::CheckPropertyCompatibility( cmComputeLinkInformation* info, const std::string& config) const @@ -4460,8 +4493,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 @@ -4542,7 +4575,7 @@ bool getTypedProperty<bool>(cmGeneratorTarget const* tgt, } const char* value = tgt->GetProperty(prop); - return cmSystemTools::IsOn(genexInterpreter->Evaluate(value, prop)); + return cmIsOn(genexInterpreter->Evaluate(value, prop)); } template <> @@ -4660,7 +4693,7 @@ std::pair<bool, const char*> consistentProperty(const char* lhs, switch (t) { case BoolType: { - bool same = cmSystemTools::IsOn(lhs) == cmSystemTools::IsOn(rhs); + bool same = cmIsOn(lhs) == cmIsOn(rhs); return std::make_pair(same, same ? lhs : nullptr); } case StringType: @@ -4691,7 +4724,7 @@ std::pair<bool, std::string> consistentProperty(const std::string& lhs, switch (t) { case BoolType: { - bool same = cmSystemTools::IsOn(lhs) == cmSystemTools::IsOn(rhs); + bool same = cmIsOn(lhs) == cmIsOn(rhs); return std::make_pair(same, same ? lhs : null_ptr); } case StringType: @@ -4718,9 +4751,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)); @@ -4733,8 +4764,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); @@ -4760,8 +4790,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()); @@ -4991,9 +5020,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. @@ -5032,13 +5060,7 @@ void cmGeneratorTarget::ComputeVersionedName(std::string& vName, std::vector<std::string> cmGeneratorTarget::GetPropertyKeys() const { - cmPropertyMap const& propsObject = this->Target->GetProperties(); - std::vector<std::string> props; - props.reserve(propsObject.size()); - for (auto const& it : propsObject) { - props.push_back(it.first); - } - return props; + return this->Target->GetProperties().GetKeys(); } void cmGeneratorTarget::ReportPropertyOrigin( @@ -5049,12 +5071,11 @@ void cmGeneratorTarget::ReportPropertyOrigin( const char* debugProp = this->Target->GetMakefile()->GetDefinition( "CMAKE_DEBUG_TARGET_PROPERTIES"); if (debugProp) { - cmSystemTools::ExpandListArgument(debugProp, debugProperties); + 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; @@ -5063,12 +5084,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); @@ -5101,10 +5119,9 @@ void cmGeneratorTarget::ExpandLinkItems( } std::vector<std::string> libs; std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(value); - cmSystemTools::ExpandListArgument(cge->Evaluate(this->LocalGenerator, config, - false, headTarget, this, - &dagChecker), - libs); + cmExpandList(cge->Evaluate(this->LocalGenerator, config, false, headTarget, + this, &dagChecker), + libs); this->LookupLinkItems(libs, cge->GetBacktrace(), items); hadHeadSensitiveCondition = cge->GetHadHeadSensitiveCondition(); } @@ -5152,7 +5169,7 @@ void cmGeneratorTarget::ComputeLinkInterface( const std::string& config, cmOptionalLinkInterface& iface, cmGeneratorTarget const* headTarget) const { - if (iface.ExplicitLibraries) { + if (iface.Explicit) { if (this->GetType() == cmStateEnums::SHARED_LIBRARY || this->GetType() == cmStateEnums::STATIC_LIBRARY || this->GetType() == cmStateEnums::INTERFACE_LIBRARY) { @@ -5209,8 +5226,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 = @@ -5296,10 +5312,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; } @@ -5485,13 +5500,41 @@ bool cmGeneratorTarget::ComputePDBOutputDir(const std::string& kind, return true; } -bool cmGeneratorTarget::HaveInstallTreeRPATH() const +bool cmGeneratorTarget::HaveInstallTreeRPATH(const std::string& config) const { - const char* install_rpath = this->GetProperty("INSTALL_RPATH"); - return (install_rpath && *install_rpath) && + std::string install_rpath; + this->GetInstallRPATH(config, install_rpath); + return !install_rpath.empty() && !this->Makefile->IsOn("CMAKE_SKIP_INSTALL_RPATH"); } +bool cmGeneratorTarget::GetBuildRPATH(const std::string& config, + std::string& rpath) const +{ + return this->GetRPATH(config, "BUILD_RPATH", rpath); +} + +bool cmGeneratorTarget::GetInstallRPATH(const std::string& config, + std::string& rpath) const +{ + return this->GetRPATH(config, "INSTALL_RPATH", rpath); +} + +bool cmGeneratorTarget::GetRPATH(const std::string& config, + const std::string& prop, + std::string& rpath) const +{ + const char* value = this->GetProperty(prop); + if (!value) { + return false; + } + + cmGeneratorExpression ge; + rpath = ge.Parse(value)->Evaluate(this->LocalGenerator, config); + + return true; +} + void cmGeneratorTarget::ComputeLinkInterfaceLibraries( const std::string& config, cmOptionalLinkInterface& iface, cmGeneratorTarget const* headTarget, bool usage_requirements_only) const @@ -5508,8 +5551,9 @@ void cmGeneratorTarget::ComputeLinkInterfaceLibraries( // libraries and executables that export symbols. const char* explicitLibraries = nullptr; std::string linkIfaceProp; - if (this->GetPolicyStatusCMP0022() != cmPolicies::OLD && - this->GetPolicyStatusCMP0022() != cmPolicies::WARN) { + bool const cmp0022NEW = (this->GetPolicyStatusCMP0022() != cmPolicies::OLD && + this->GetPolicyStatusCMP0022() != cmPolicies::WARN); + if (cmp0022NEW) { // CMP0022 NEW behavior is to use INTERFACE_LINK_LIBRARIES. linkIfaceProp = "INTERFACE_LINK_LIBRARIES"; explicitLibraries = this->GetProperty(linkIfaceProp); @@ -5519,8 +5563,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. @@ -5564,15 +5607,14 @@ void cmGeneratorTarget::ComputeLinkInterfaceLibraries( return; } iface.Exists = true; - iface.ExplicitLibraries = explicitLibraries; + iface.Explicit = cmp0022NEW || explicitLibraries != nullptr; if (explicitLibraries) { // The interface libraries have been explicitly set. this->ExpandLinkItems(linkIfaceProp, explicitLibraries, config, headTarget, usage_requirements_only, iface.Libraries, iface.HadHeadSensitiveCondition); - } else if (this->GetPolicyStatusCMP0022() == cmPolicies::WARN || - this->GetPolicyStatusCMP0022() == cmPolicies::OLD) + } else if (!cmp0022NEW) // If CMP0022 is NEW then the plain tll signature sets the // INTERFACE_LINK_LIBRARIES, so if we get here then the project // cleared the property explicitly and we should not fall back @@ -5653,12 +5695,11 @@ const cmLinkInterface* cmGeneratorTarget::GetImportLinkInterface( if (!iface.AllDone) { iface.AllDone = true; iface.Multiplicity = info->Multiplicity; - cmSystemTools::ExpandListArgument(info->Languages, iface.Languages); + cmExpandList(info->Languages, iface.Languages); this->ExpandLinkItems(info->LibrariesProp, info->Libraries, config, headTarget, usage_requirements_only, iface.Libraries, iface.HadHeadSensitiveCondition); - std::vector<std::string> deps; - cmSystemTools::ExpandListArgument(info->SharedDeps, deps); + std::vector<std::string> deps = cmExpandedList(info->SharedDeps); this->LookupLinkItems(deps, cmListFileBacktrace(), iface.SharedDeps); } @@ -5727,8 +5768,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); } @@ -5756,8 +5796,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")) { @@ -5767,8 +5806,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")) { @@ -5778,13 +5816,12 @@ 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 = cmSystemTools::IsOn(config_no_soname); + info.NoSOName = cmIsOn(config_no_soname); } else if (const char* no_soname = this->GetProperty("IMPORTED_NO_SONAME")) { - info.NoSOName = cmSystemTools::IsOn(no_soname); + info.NoSOName = cmIsOn(no_soname); } } @@ -5793,8 +5830,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")) { @@ -5804,8 +5840,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 = @@ -5816,8 +5852,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 = @@ -5838,8 +5874,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 = @@ -5946,8 +5982,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; - cmSystemTools::ExpandListArgument(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); @@ -6091,7 +6126,8 @@ bool cmGeneratorTarget::HaveBuildTreeRPATH(const std::string& config) const if (this->GetPropertyAsBool("SKIP_BUILD_RPATH")) { return false; } - if (this->GetProperty("BUILD_RPATH")) { + std::string build_rpath; + if (this->GetBuildRPATH(config, build_rpath)) { return true; } if (cmLinkImplementationLibraries const* impl = @@ -6138,8 +6174,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( @@ -6160,7 +6195,7 @@ void cmGeneratorTarget::ComputeLinkImplementationLibraries( std::unique_ptr<cmCompiledGeneratorExpression> const cge = ge.Parse(*le); std::string const& evaluated = cge->Evaluate(this->LocalGenerator, config, false, head, &dagChecker); - cmSystemTools::ExpandListArgument(evaluated, llibs); + cmExpandList(evaluated, llibs); if (cge->GetHadHeadSensitiveCondition()) { impl.HadHeadSensitiveCondition = true; } @@ -6317,8 +6352,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; @@ -6337,15 +6372,24 @@ bool cmGeneratorTarget::HasImportLibrary(std::string const& config) const this->IsExecutableWithExports()) && // Assemblies which have only managed code do not have // import libraries. - this->GetManagedType(config) != ManagedType::Managed); + this->GetManagedType(config) != ManagedType::Managed) || + (this->Target->IsAIX() && this->IsExecutableWithExports()); +} + +bool cmGeneratorTarget::NeedImportLibraryName(std::string const& config) const +{ + return this->HasImportLibrary(config) || + // On DLL platforms we always generate the import library name + // just in case the sources have export markup. + (this->IsDLLPlatform() && + (this->GetType() == cmStateEnums::EXECUTABLE || + this->GetType() == cmStateEnums::MODULE_LIBRARY)); } std::string cmGeneratorTarget::GetSupportDirectory() const { - std::string dir = this->LocalGenerator->GetCurrentBinaryDirectory(); - dir += "/CMakeFiles"; - dir += "/"; - 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 0e0ee6a..3874738 100644 --- a/Source/cmGeneratorTarget.h +++ b/Source/cmGeneratorTarget.h @@ -14,6 +14,7 @@ #include <set> #include <stddef.h> #include <string> +#include <unordered_map> #include <utility> #include <vector> @@ -25,6 +26,9 @@ class cmMakefile; class cmSourceFile; class cmTarget; +struct cmGeneratorExpressionContext; +struct cmGeneratorExpressionDAGChecker; + class cmGeneratorTarget { public: @@ -674,7 +678,14 @@ public: class TargetPropertyEntry; - bool HaveInstallTreeRPATH() const; + std::string EvaluateInterfaceProperty( + std::string const& prop, cmGeneratorExpressionContext* context, + cmGeneratorExpressionDAGChecker* dagCheckerParent) const; + + bool HaveInstallTreeRPATH(const std::string& config) const; + + bool GetBuildRPATH(const std::string& config, std::string& rpath) const; + bool GetInstallRPATH(const std::string& config, std::string& rpath) const; /** Whether this library has \@rpath and platform supports it. */ bool HasMacOSXRpathInstallNameDir(const std::string& config) const; @@ -740,9 +751,13 @@ private: mutable std::map<std::string, bool> DebugCompatiblePropertiesDone; - const char* GetFilePrefixInternal(cmStateEnums::ArtifactType artifact, + bool NeedImportLibraryName(std::string const& config) const; + + const char* GetFilePrefixInternal(std::string const& config, + cmStateEnums::ArtifactType artifact, const std::string& language = "") const; - const char* GetFileSuffixInternal(cmStateEnums::ArtifactType artifact, + const char* GetFileSuffixInternal(std::string const& config, + cmStateEnums::ArtifactType artifact, const std::string& language = "") const; std::string GetFullNameInternal(const std::string& config, @@ -842,6 +857,10 @@ private: mutable std::vector<AllConfigSource> AllConfigSources; void ComputeAllConfigSources() const; + mutable std::unordered_map<std::string, bool> MaybeInterfacePropertyExists; + bool MaybeHaveInterfaceProperty(std::string const& prop, + cmGeneratorExpressionContext* context) const; + std::vector<TargetPropertyEntry*> IncludeDirectoriesEntries; std::vector<TargetPropertyEntry*> CompileOptionsEntries; std::vector<TargetPropertyEntry*> CompileFeaturesEntries; @@ -906,13 +925,15 @@ private: mutable bool DebugSourcesDone; mutable bool LinkImplementationLanguageIsContextDependent; mutable bool UtilityItemsDone; - bool DLLPlatform; bool ComputePDBOutputDir(const std::string& kind, const std::string& config, std::string& out) const; ManagedType CheckManagedType(std::string const& propval) const; + bool GetRPATH(const std::string& config, const std::string& prop, + std::string& rpath) const; + public: const std::vector<const cmGeneratorTarget*>& GetLinkImplementationClosure( const std::string& config) const; diff --git a/Source/cmGetCMakePropertyCommand.cxx b/Source/cmGetCMakePropertyCommand.cxx index fc82fee..ff4e312 100644 --- a/Source/cmGetCMakePropertyCommand.cxx +++ b/Source/cmGetCMakePropertyCommand.cxx @@ -4,19 +4,18 @@ #include <set> -#include "cmAlgorithms.h" +#include "cmExecutionStatus.h" #include "cmGlobalGenerator.h" #include "cmMakefile.h" #include "cmState.h" - -class cmExecutionStatus; +#include "cmStringAlgorithms.h" // 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.c_str()); + status.GetMakefile().AddDefinition(variable, output); return true; } diff --git a/Source/cmGetCMakePropertyCommand.h b/Source/cmGetCMakePropertyCommand.h index 1f29c78..7a6728c 100644 --- a/Source/cmGetCMakePropertyCommand.h +++ b/Source/cmGetCMakePropertyCommand.h @@ -8,21 +8,9 @@ #include <string> #include <vector> -#include "cmCommand.h" - class cmExecutionStatus; -class cmGetCMakePropertyCommand : public cmCommand -{ -public: - cmCommand* Clone() override { return new 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 a92eb71..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.c_str()); + 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,16 +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) { - if (prop) { - this->Makefile->AddDefinition(variable, prop); - return; - } - this->Makefile->AddDefinition(variable, ""); + makefile.AddDefinition(variable, prop ? prop : ""); +} } diff --git a/Source/cmGetDirectoryPropertyCommand.h b/Source/cmGetDirectoryPropertyCommand.h index 02ea056..f356ea5 100644 --- a/Source/cmGetDirectoryPropertyCommand.h +++ b/Source/cmGetDirectoryPropertyCommand.h @@ -8,24 +8,9 @@ #include <string> #include <vector> -#include "cmCommand.h" - class cmExecutionStatus; -class cmGetDirectoryPropertyCommand : public cmCommand -{ -public: - cmCommand* Clone() override { return new 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 163b4c8..7d91a75 100644 --- a/Source/cmGetFilenameComponentCommand.cxx +++ b/Source/cmGetFilenameComponentCommand.cxx @@ -2,26 +2,26 @@ 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()); - if (cacheValue && !cmSystemTools::IsNOTFOUND(cacheValue)) { + const char* cacheValue = status.GetMakefile().GetDefinition(args.front()); + if (cacheValue && !cmIsNOTFOUND(cacheValue)) { return true; } } @@ -32,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; } @@ -64,7 +64,7 @@ bool cmGetFilenameComponentCommand::InitialPass( // First assume the path to the program was specified with no // arguments and with no quoting or escaping for spaces. // Only bother doing this if there is non-whitespace. - if (!cmSystemTools::TrimWhitespace(filename).empty()) { + if (!cmTrimWhitespace(filename).empty()) { result = cmSystemTools::FindProgram(filename); } @@ -96,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; @@ -113,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.c_str()); + status.GetMakefile().AddDefinition(storeArgs, programArgs); } - this->Makefile->AddDefinition(args.front(), result.c_str()); + status.GetMakefile().AddDefinition(args.front(), result); } return true; diff --git a/Source/cmGetFilenameComponentCommand.h b/Source/cmGetFilenameComponentCommand.h index 8c26655..db5293b 100644 --- a/Source/cmGetFilenameComponentCommand.h +++ b/Source/cmGetFilenameComponentCommand.h @@ -8,30 +8,15 @@ #include <string> #include <vector> -#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. - */ - cmCommand* Clone() override { return new 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 039f439..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.c_str()); - } 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.c_str()); - } 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 c3f653e..cc600f4 100644 --- a/Source/cmGetPropertyCommand.h +++ b/Source/cmGetPropertyCommand.h @@ -8,50 +8,9 @@ #include <string> #include <vector> -#include "cmCommand.h" - class cmExecutionStatus; -class cmGetPropertyCommand : public cmCommand -{ -public: - cmGetPropertyCommand(); - - cmCommand* Clone() override { return new 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 75879a5..a16076d 100644 --- a/Source/cmGetSourceFilePropertyCommand.cxx +++ b/Source/cmGetSourceFilePropertyCommand.cxx @@ -25,7 +25,7 @@ bool cmGetSourceFilePropertyCommand::InitialPass( } if (sf) { if (args[2] == "LANGUAGE") { - this->Makefile->AddDefinition(var, sf->GetLanguage().c_str()); + this->Makefile->AddDefinition(var, sf->GetLanguage()); return true; } const char* prop = nullptr; diff --git a/Source/cmGetSourceFilePropertyCommand.h b/Source/cmGetSourceFilePropertyCommand.h index 43bc330..387a7f4 100644 --- a/Source/cmGetSourceFilePropertyCommand.h +++ b/Source/cmGetSourceFilePropertyCommand.h @@ -8,6 +8,8 @@ #include <string> #include <vector> +#include "cm_memory.hxx" + #include "cmCommand.h" class cmExecutionStatus; @@ -15,7 +17,10 @@ class cmExecutionStatus; class cmGetSourceFilePropertyCommand : public cmCommand { public: - cmCommand* Clone() override { return new cmGetSourceFilePropertyCommand; } + std::unique_ptr<cmCommand> Clone() override + { + return cm::make_unique<cmGetSourceFilePropertyCommand>(); + } /** * This is called when the command is first encountered in diff --git a/Source/cmGetTargetPropertyCommand.cxx b/Source/cmGetTargetPropertyCommand.cxx index fc0e9c6..07aaf02 100644 --- a/Source/cmGetTargetPropertyCommand.cxx +++ b/Source/cmGetTargetPropertyCommand.cxx @@ -75,9 +75,9 @@ bool cmGetTargetPropertyCommand::InitialPass( } } if (prop_exists) { - this->Makefile->AddDefinition(var, prop.c_str()); + this->Makefile->AddDefinition(var, prop); return true; } - this->Makefile->AddDefinition(var, (var + "-NOTFOUND").c_str()); + this->Makefile->AddDefinition(var, var + "-NOTFOUND"); return true; } diff --git a/Source/cmGetTargetPropertyCommand.h b/Source/cmGetTargetPropertyCommand.h index 63ee5fd..1a53195 100644 --- a/Source/cmGetTargetPropertyCommand.h +++ b/Source/cmGetTargetPropertyCommand.h @@ -8,6 +8,8 @@ #include <string> #include <vector> +#include "cm_memory.hxx" + #include "cmCommand.h" class cmExecutionStatus; @@ -15,7 +17,10 @@ class cmExecutionStatus; class cmGetTargetPropertyCommand : public cmCommand { public: - cmCommand* Clone() override { return new cmGetTargetPropertyCommand; } + std::unique_ptr<cmCommand> Clone() override + { + return cm::make_unique<cmGetTargetPropertyCommand>(); + } /** * This is called when the command is first encountered in diff --git a/Source/cmGetTestPropertyCommand.h b/Source/cmGetTestPropertyCommand.h index 4a74f59..a53a7f7 100644 --- a/Source/cmGetTestPropertyCommand.h +++ b/Source/cmGetTestPropertyCommand.h @@ -8,6 +8,8 @@ #include <string> #include <vector> +#include "cm_memory.hxx" + #include "cmCommand.h" class cmExecutionStatus; @@ -15,7 +17,10 @@ class cmExecutionStatus; class cmGetTestPropertyCommand : public cmCommand { public: - cmCommand* Clone() override { return new cmGetTestPropertyCommand; } + std::unique_ptr<cmCommand> Clone() override + { + return cm::make_unique<cmGetTestPropertyCommand>(); + } /** * This is called when the command is first encountered in diff --git a/Source/cmGhsMultiTargetGenerator.cxx b/Source/cmGhsMultiTargetGenerator.cxx index b80da72..e7b20ed 100644 --- a/Source/cmGhsMultiTargetGenerator.cxx +++ b/Source/cmGhsMultiTargetGenerator.cxx @@ -18,13 +18,16 @@ #include "cmStateDirectory.h" #include "cmStateSnapshot.h" #include "cmStateTypes.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmTarget.h" #include <algorithm> +#include <memory> #include <ostream> #include <set> #include <utility> +#include <vector> cmGhsMultiTargetGenerator::cmGhsMultiTargetGenerator(cmGeneratorTarget* target) : GeneratorTarget(target) @@ -72,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; } @@ -84,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; } @@ -120,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); @@ -344,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); @@ -392,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)); } @@ -440,12 +440,12 @@ void cmGhsMultiTargetGenerator::WriteCustomCommandsHelper( // This command was specified as a path to a file in the // current directory. Add a leading "./" so it can run // without the current directory being in the search path. - cmd = "./" + cmd; + cmd = cmStrCat("./", cmd); } cmd = this->LocalGenerator->ConvertToOutputFormat( cmd, cmOutputConverter::SHELL); if (useCall) { - cmd = "call " + cmd; + cmd = cmStrCat("call ", cmd); } ccg.AppendArguments(c, cmd); cmdLines.push_back(std::move(cmd)); @@ -465,8 +465,7 @@ void cmGhsMultiTargetGenerator::WriteSourceProperty( { const char* prop = sf->GetProperty(propName); if (prop) { - std::vector<std::string> list; - cmSystemTools::ExpandListArgument(prop, list); + std::vector<std::string> list = cmExpandedList(prop); for (auto& p : list) { fout << " " << propFlag << p << std::endl; } @@ -558,24 +557,19 @@ void cmGhsMultiTargetGenerator::WriteSources(std::ostream& fout_proj) for (auto& sg : groupFilesList) { std::ostream* fout; bool useProjectFile = - cmSystemTools::IsOn( - this->GeneratorTarget->GetProperty("GHS_NO_SOURCE_GROUP_FILE")) || - cmSystemTools::IsOn( - this->Makefile->GetDefinition("CMAKE_GHS_NO_SOURCE_GROUP_FILE")); + cmIsOn(this->GeneratorTarget->GetProperty("GHS_NO_SOURCE_GROUP_FILE")) || + cmIsOn(this->Makefile->GetDefinition("CMAKE_GHS_NO_SOURCE_GROUP_FILE")); if (useProjectFile || sg.empty()) { fout = &fout_proj; } else { // 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); @@ -667,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); @@ -737,8 +729,7 @@ bool cmGhsMultiTargetGenerator::DetermineIfIntegrityApp() { const char* p = this->GeneratorTarget->GetProperty("ghs_integrity_app"); if (p) { - return cmSystemTools::IsOn( - this->GeneratorTarget->GetProperty("ghs_integrity_app")); + return cmIsOn(this->GeneratorTarget->GetProperty("ghs_integrity_app")); } std::vector<cmSourceFile*> sources; this->GeneratorTarget->GetSourceFiles(sources, this->ConfigName); 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 9afc15a..4342e9f 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -44,7 +44,7 @@ #include "cmWorkingDirectory.h" #include "cmake.h" -#if defined(CMAKE_BUILD_WITH_CMAKE) +#if !defined(CMAKE_BOOTSTRAP) # include "cmCryptoHash.h" # include "cmQtAutoGenGlobalInitializer.h" # include "cm_jsoncpp_value.h" @@ -92,7 +92,6 @@ cmGlobalGenerator::cmGlobalGenerator(cmake* cm) // how long to let try compiles run this->TryCompileTimeout = cmDuration::zero(); - this->ExtraGenerator = nullptr; this->CurrentConfigureMakefile = nullptr; this->TryCompileOuterMakefile = nullptr; @@ -113,10 +112,9 @@ cmGlobalGenerator::cmGlobalGenerator(cmake* cm) cmGlobalGenerator::~cmGlobalGenerator() { this->ClearGeneratorMembers(); - delete this->ExtraGenerator; } -#if defined(CMAKE_BUILD_WITH_CMAKE) +#if !defined(CMAKE_BOOTSTRAP) Json::Value cmGlobalGenerator::GetJson() const { Json::Value generator = Json::objectValue; @@ -188,15 +186,15 @@ std::string cmGlobalGenerator::SelectMakeProgram( const std::string& inMakeProgram, const std::string& makeDefault) const { std::string makeProgram = inMakeProgram; - if (cmSystemTools::IsOff(makeProgram)) { + if (cmIsOff(makeProgram)) { const char* makeProgramCSTR = this->CMakeInstance->GetCacheDefinition("CMAKE_MAKE_PROGRAM"); - if (cmSystemTools::IsOff(makeProgramCSTR)) { + if (cmIsOff(makeProgramCSTR)) { makeProgram = makeDefault; } else { makeProgram = makeProgramCSTR; } - if (cmSystemTools::IsOff(makeProgram) && !makeProgram.empty()) { + if (cmIsOff(makeProgram) && !makeProgram.empty()) { makeProgram = "CMAKE_MAKE_PROGRAM-NOTFOUND"; } } @@ -207,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) { @@ -302,7 +298,7 @@ bool cmGlobalGenerator::CheckTargetsForMissingSources() const if (target->GetType() == cmStateEnums::TargetType::GLOBAL_TARGET || target->GetType() == cmStateEnums::TargetType::INTERFACE_LIBRARY || target->GetType() == cmStateEnums::TargetType::UTILITY || - cmSystemTools::IsOn(target->GetProperty("ghs_integrity_app"))) { + cmIsOn(target->GetProperty("ghs_integrity_app"))) { continue; } @@ -370,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 @@ -384,14 +379,14 @@ bool cmGlobalGenerator::FindMakeProgram(cmMakefile* mf) return false; } if (!mf->GetDefinition("CMAKE_MAKE_PROGRAM") || - cmSystemTools::IsOff(mf->GetDefinition("CMAKE_MAKE_PROGRAM"))) { + cmIsOff(mf->GetDefinition("CMAKE_MAKE_PROGRAM"))) { std::string setMakeProgram = mf->GetModulesFile(this->FindMakeProgramFile); if (!setMakeProgram.empty()) { mf->ReadListFile(setMakeProgram); } } if (!mf->GetDefinition("CMAKE_MAKE_PROGRAM") || - cmSystemTools::IsOff(mf->GetDefinition("CMAKE_MAKE_PROGRAM"))) { + cmIsOff(mf->GetDefinition("CMAKE_MAKE_PROGRAM"))) { std::ostringstream err; err << "CMake was unable to find a build program corresponding to \"" << this->GetName() << "\". CMAKE_MAKE_PROGRAM is not set. You " @@ -411,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); } @@ -499,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."; @@ -514,9 +507,9 @@ void cmGlobalGenerator::EnableLanguage( bool fatalError = false; - mf->AddDefinition("RUN_CONFIGURE", true); - std::string rootBin = this->CMakeInstance->GetHomeOutputDirectory(); - rootBin += "/CMakeFiles"; + mf->AddDefinitionBool("RUN_CONFIGURE", true); + 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 @@ -524,11 +517,11 @@ void cmGlobalGenerator::EnableLanguage( if (!this->ConfiguredFilesPath.empty()) { rootBin = this->ConfiguredFilesPath; } - rootBin += "/"; + rootBin += '/'; rootBin += cmVersion::GetCMakeVersion(); // set the dir for parent files so they can be used by modules - mf->AddDefinition("CMAKE_PLATFORM_INFO_DIR", rootBin.c_str()); + mf->AddDefinition("CMAKE_PLATFORM_INFO_DIR", rootBin); if (!this->CMakeInstance->GetIsInTryCompile()) { // Keep a mark in the cache to indicate that we've initialized the @@ -588,16 +581,14 @@ void cmGlobalGenerator::EnableLanguage( windowsVersionString << osviex.dwMajorVersion << "." << osviex.dwMinorVersion << "." << osviex.dwBuildNumber; - mf->AddDefinition("CMAKE_HOST_SYSTEM_VERSION", - windowsVersionString.str().c_str()); + mf->AddDefinition("CMAKE_HOST_SYSTEM_VERSION", windowsVersionString.str()); #endif // Read the DetermineSystem file std::string systemFile = mf->GetModulesFile("CMakeDetermineSystem.cmake"); 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); } @@ -663,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 @@ -697,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: " + @@ -715,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); } @@ -766,16 +743,11 @@ 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 || - cmSystemTools::IsNOTFOUND(compilerFile)) { + if (!compilerFile || !*compilerFile || cmIsNOTFOUND(compilerFile)) { /* clang-format off */ noCompiler << "No " << compilerName << " could be found.\n" @@ -806,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, @@ -820,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); @@ -847,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); @@ -884,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); } @@ -924,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() && @@ -959,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() && @@ -995,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() && @@ -1100,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; } @@ -1124,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; } @@ -1151,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; - cmSystemTools::ExpandListArgument(ignoreExts, extensionList); + std::vector<std::string> extensionList = cmExpandedList(ignoreExts); for (std::string const& i : extensionList) { this->IgnoreExtensions[i] = true; } @@ -1164,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; - cmSystemTools::ExpandListArgument(exts, extensionList); + std::vector<std::string> extensionList = cmExpandedList(exts); for (std::string const& i : extensionList) { this->ExtensionToLanguage[i] = l; } @@ -1280,10 +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 += "/"; - f += *log; + std::string f = cmStrCat(this->CMakeInstance->GetHomeOutputDirectory(), + "/CMakeFiles/", *log); if (cmSystemTools::FileExists(f)) { msg << "\nSee also \"" << f << "\"."; } @@ -1500,7 +1452,7 @@ void cmGlobalGenerator::Generate() this->WriteSummary(); - if (this->ExtraGenerator != nullptr) { + if (this->ExtraGenerator) { this->ExtraGenerator->Generate(); } @@ -1550,7 +1502,7 @@ bool cmGlobalGenerator::ComputeTargetDepends() bool cmGlobalGenerator::QtAutoGen() { -#ifdef CMAKE_BUILD_WITH_CMAKE +#ifndef CMAKE_BOOTSTRAP cmQtAutoGenGlobalInitializer initializer(this->LocalGenerators); return initializer.generate(); #else @@ -1609,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)); } } @@ -1624,9 +1576,8 @@ void cmGlobalGenerator::FinalizeTargetCompileInfo() "CMAKE_" + li + "_STANDARD_INCLUDE_DIRECTORIES"; std::string const& standardIncludesStr = mf->GetSafeDefinition(standardIncludesVar); - std::vector<std::string> standardIncludesVec; - cmSystemTools::ExpandListArgument(standardIncludesStr, - standardIncludesVec); + std::vector<std::string> standardIncludesVec = + cmExpandedList(standardIncludesStr); standardIncludesSet.insert(standardIncludesVec.begin(), standardIncludesVec.end()); } @@ -1713,17 +1664,15 @@ void cmGlobalGenerator::CheckTargetProperties() continue; } for (auto const& lib : target.second.GetOriginalLinkLibraries()) { - if (lib.first.size() > 9 && - cmSystemTools::IsNOTFOUND(lib.first.c_str())) { + if (lib.first.size() > 9 && cmIsNOTFOUND(lib.first)) { std::string varName = lib.first.substr(0, lib.first.size() - 9); 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; } } @@ -1737,17 +1686,18 @@ void cmGlobalGenerator::CheckTargetProperties() std::string incDirs = cmGeneratorExpression::Preprocess( incDirProp, cmGeneratorExpression::StripAllGeneratorExpressions); - cmSystemTools::ExpandListArgument(incDirs, incs); + cmExpandList(incDirs, incs); for (std::string const& incDir : incs) { - if (incDir.size() > 9 && cmSystemTools::IsNOTFOUND(incDir.c_str())) { + if (incDir.size() > 9 && cmIsNOTFOUND(incDir)) { std::string varName = incDir.substr(0, incDir.size() - 9); 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; } } @@ -1846,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"; @@ -1952,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; @@ -2056,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"); } } @@ -2157,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) @@ -2273,14 +2223,6 @@ bool cmGlobalGenerator::NameResolvesToFramework( return false; } -inline std::string removeQuotes(const std::string& s) -{ - if (s.front() == '\"' && s.back() == '\"') { - return s.substr(1, s.size() - 2); - } - return s; -} - bool cmGlobalGenerator::CheckCMP0037(std::string const& targetName, std::string const& reason) const { @@ -2335,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; } @@ -2368,7 +2310,7 @@ void cmGlobalGenerator::AddGlobalTarget_Package( } else { const char* noPackageAll = mf->GetDefinition("CMAKE_SKIP_PACKAGE_ALL_DEPENDENCY"); - if (!noPackageAll || cmSystemTools::IsOff(noPackageAll)) { + if (!noPackageAll || cmIsOff(noPackageAll)) { gti.Depends.emplace_back(this->GetAllTargetName()); } } @@ -2384,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; } @@ -2537,7 +2479,7 @@ void cmGlobalGenerator::AddGlobalTarget_Install( } else { const char* noall = mf->GetDefinition("CMAKE_SKIP_INSTALL_ALL_DEPENDENCY"); - if (!noall || cmSystemTools::IsOff(noall)) { + if (!noall || cmIsOff(noall)) { gti.Depends.emplace_back(this->GetAllTargetName()); } } @@ -2620,7 +2562,7 @@ bool cmGlobalGenerator::UseFolderProperty() const // If this property is defined, let the setter turn this on or off... // if (prop) { - return cmSystemTools::IsOn(prop); + return cmIsOn(prop); } // By default, this feature is OFF, since it is not supported in the @@ -2664,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"); @@ -2715,15 +2656,14 @@ 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( cmExternalMakefileProjectGenerator* extraGenerator) { - this->ExtraGenerator = extraGenerator; - if (this->ExtraGenerator != nullptr) { + this->ExtraGenerator.reset(extraGenerator); + if (this->ExtraGenerator) { this->ExtraGenerator->SetGlobalGenerator(this); } } @@ -2832,7 +2772,7 @@ std::set<std::string> const& cmGlobalGenerator::GetDirectoryContent( void cmGlobalGenerator::AddRuleHash(const std::vector<std::string>& outputs, std::string const& content) { -#if defined(CMAKE_BUILD_WITH_CMAKE) +#if !defined(CMAKE_BOOTSTRAP) // Ignore if there are no outputs. if (outputs.empty()) { return; @@ -2862,11 +2802,9 @@ void cmGlobalGenerator::AddRuleHash(const std::vector<std::string>& outputs, void cmGlobalGenerator::CheckRuleHashes() { -#if defined(CMAKE_BUILD_WITH_CMAKE) +#if !defined(CMAKE_BOOTSTRAP) std::string home = this->GetCMakeInstance()->GetHomeOutputDirectory(); - std::string pfile = home; - pfile += "/CMakeFiles"; - pfile += "/CMakeRuleHashes.txt"; + std::string pfile = cmStrCat(home, "/CMakeFiles/CMakeRuleHashes.txt"); this->CheckRuleHashes(pfile, home); this->WriteRuleHashes(pfile); #endif @@ -2942,9 +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"; - fname += "/TargetDirectories.txt"; + std::string fname = cmStrCat(this->CMakeInstance->GetHomeOutputDirectory(), + "/CMakeFiles/TargetDirectories.txt"); cmGeneratedFileStream fout(fname); for (cmLocalGenerator* lg : this->LocalGenerators) { @@ -2962,11 +2899,10 @@ 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"; -#ifdef CMAKE_BUILD_WITH_CMAKE +#ifndef CMAKE_BOOTSTRAP // Check whether labels are enabled for this target. const char* targetLabels = target->GetProperty("LABELS"); const char* directoryLabels = @@ -2988,7 +2924,7 @@ void cmGlobalGenerator::WriteSummary(cmGeneratorTarget* target) // List the target-wide labels. All sources in the target get // these labels. if (targetLabels) { - cmSystemTools::ExpandListArgument(targetLabels, labels); + cmExpandList(targetLabels, labels); if (!labels.empty()) { fout << "# Target labels\n"; for (std::string const& l : labels) { @@ -3003,12 +2939,11 @@ void cmGlobalGenerator::WriteSummary(cmGeneratorTarget* target) std::vector<std::string> cmakeDirectoryLabelsList; if (directoryLabels) { - cmSystemTools::ExpandListArgument(directoryLabels, directoryLabelsList); + cmExpandList(directoryLabels, directoryLabelsList); } if (cmakeDirectoryLabels) { - cmSystemTools::ExpandListArgument(cmakeDirectoryLabels, - cmakeDirectoryLabelsList); + cmExpandList(cmakeDirectoryLabels, cmakeDirectoryLabelsList); } if (!directoryLabelsList.empty() || !cmakeDirectoryLabelsList.empty()) { @@ -3045,7 +2980,7 @@ void cmGlobalGenerator::WriteSummary(cmGeneratorTarget* target) if (const char* svalue = sf->GetProperty("LABELS")) { labels.clear(); Json::Value& lj_source_labels = lj_source["labels"] = Json::arrayValue; - cmSystemTools::ExpandListArgument(svalue, labels); + cmExpandList(svalue, labels); for (std::string const& label : labels) { fout << " " << label << "\n"; lj_source_labels.append(label); @@ -3132,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/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index db96489..830974d 100644 --- a/Source/cmGlobalGenerator.h +++ b/Source/cmGlobalGenerator.h @@ -7,6 +7,7 @@ #include <iosfwd> #include <map> +#include <memory> #include <set> #include <string> #include <unordered_map> @@ -18,12 +19,13 @@ #include "cmDuration.h" #include "cmExportSetMap.h" #include "cmStateSnapshot.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmTarget.h" #include "cmTargetDepend.h" #include "cm_codecvt.hxx" -#if defined(CMAKE_BUILD_WITH_CMAKE) +#if !defined(CMAKE_BOOTSTRAP) # include "cmFileLockPool.h" # include "cm_jsoncpp_value.h" #endif @@ -107,7 +109,7 @@ public: return codecvt::None; } -#if defined(CMAKE_BUILD_WITH_CMAKE) +#if !defined(CMAKE_BOOTSTRAP) /** Get a JSON object describing the generator. */ virtual Json::Value GetJson() const; #endif @@ -460,7 +462,7 @@ public: const std::set<const cmGeneratorTarget*>& GetFilenameTargetDepends( cmSourceFile* sf) const; -#if defined(CMAKE_BUILD_WITH_CMAKE) +#if !defined(CMAKE_BOOTSTRAP) cmFileLockPool& GetFileLockPool() { return FileLockPool; } #endif @@ -618,7 +620,7 @@ private: void ComputeBuildFileGenerators(); - cmExternalMakefileProjectGenerator* ExtraGenerator; + std::unique_ptr<cmExternalMakefileProjectGenerator> ExtraGenerator; // track files replaced during a Generate std::vector<std::string> FilesReplacedDuringGenerate; @@ -663,7 +665,7 @@ private: mutable std::map<cmSourceFile*, std::set<cmGeneratorTarget const*>> FilenameTargetDepends; -#if defined(CMAKE_BUILD_WITH_CMAKE) +#if !defined(CMAKE_BOOTSTRAP) // Pool of file locks cmFileLockPool FileLockPool; #endif diff --git a/Source/cmGlobalGhsMultiGenerator.cxx b/Source/cmGlobalGhsMultiGenerator.cxx index b69dea0..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" @@ -11,6 +12,7 @@ #include "cmMakefile.h" #include "cmState.h" #include "cmStateTypes.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmVersion.h" #include "cmake.h" @@ -55,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; } @@ -76,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 @@ -97,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; } @@ -111,7 +109,7 @@ bool cmGlobalGhsMultiGenerator::SetGeneratorToolset(std::string const& ts, mf->AddCacheDefinition("CMAKE_MAKE_PROGRAM", gbuild.c_str(), "build program to use", cmStateEnums::INTERNAL, true); - mf->AddDefinition("CMAKE_SYSTEM_VERSION", tsp.c_str()); + mf->AddDefinition("CMAKE_SYSTEM_VERSION", tsp); return true; } @@ -138,24 +136,20 @@ bool cmGlobalGhsMultiGenerator::SetGeneratorPlatform(std::string const& p, /* check if OS location has been updated by platform scripts */ std::string platform = mf->GetSafeDefinition("GHS_TARGET_PLATFORM"); std::string osdir = mf->GetSafeDefinition("GHS_OS_DIR"); - if (cmSystemTools::IsOff(osdir.c_str()) && - platform.find("integrity") != std::string::npos) { + 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() && - cmSystemTools::IsOff(this->OsDir) && - !cmSystemTools::IsOff(osdir)) { + 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; @@ -163,17 +157,15 @@ bool cmGlobalGhsMultiGenerator::SetGeneratorPlatform(std::string const& p, // Determine GHS_BSP_NAME std::string bspName = mf->GetSafeDefinition("GHS_BSP_NAME"); - if (cmSystemTools::IsOff(bspName.c_str()) && - platform.find("integrity") != std::string::npos) { + if (cmIsOff(bspName) && platform.find("integrity") != std::string::npos) { bspName = "sim" + arch; /* write back the calculate name for next time */ 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); } @@ -334,18 +326,18 @@ void cmGlobalGhsMultiGenerator::WriteTopLevelProject(std::ostream& fout, // Specify BSP option if supplied by user const char* bspName = this->GetCMakeInstance()->GetCacheDefinition("GHS_BSP_NAME"); - if (!cmSystemTools::IsOff(bspName)) { + if (!cmIsOff(bspName)) { fout << " -bsp " << bspName << std::endl; } // Specify OS DIR if supplied by user // -- not all platforms require this entry in the project file - if (!cmSystemTools::IsOff(this->OsDir.c_str())) { + if (!cmIsOff(this->OsDir)) { const char* osDirOption = this->GetCMakeInstance()->GetCacheDefinition("GHS_OS_DIR_OPTION"); std::replace(this->OsDir.begin(), this->OsDir.end(), '\\', '/'); fout << " "; - if (cmSystemTools::IsOff(osDirOption)) { + if (cmIsOff(osDirOption)) { fout << ""; } else { fout << osDirOption; @@ -404,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) { @@ -418,17 +410,17 @@ void cmGlobalGhsMultiGenerator::WriteTargets(cmLocalGenerator* root) } // create target build file - std::string name = target->GetName() + ".tgt" + FILE_EXTENSION; - std::string fname = rootBinaryDir + "/" + name; + std::string name = cmStrCat(target->GetName(), ".tgt", FILE_EXTENSION); + std::string fname = cmStrCat(rootBinaryDir, "/", name); cmGeneratedFileStream fbld(fname); fbld.SetCopyIfDifferent(true); this->WriteFileHeader(fbld); GhsMultiGpj::WriteGpjTag(GhsMultiGpj::PROJECT, fbld); std::vector<cmGeneratorTarget const*> build; if (ComputeTargetBuildOrder(target, build)) { - std::string message = "The inter-target dependency graph for target [" + - target->GetName() + "] had a cycle.\n"; - cmSystemTools::Error(message); + cmSystemTools::Error( + cmStrCat("The inter-target dependency graph for target [", + target->GetName(), "] had a cycle.\n")); } else { for (auto& tgt : build) { WriteProjectLine(fbld, tgt, root, rootBinaryDir); @@ -469,7 +461,7 @@ void cmGlobalGhsMultiGenerator::WriteAllTarget( if (t->GetType() == cmStateEnums::INTERFACE_LIBRARY) { continue; } - if (!cmSystemTools::IsOn(t->GetProperty("EXCLUDE_FROM_ALL"))) { + if (!cmIsOn(t->GetProperty("EXCLUDE_FROM_ALL"))) { defaultTargets.push_back(t); } } @@ -480,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 || @@ -539,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); @@ -588,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) { @@ -623,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; - cmSystemTools::ExpandListArgument(std::string(ghsGpjMacros), expandedList); + std::vector<std::string> expandedList = + cmExpandedList(std::string(ghsGpjMacros)); for (std::string const& arg : expandedList) { fout << "macro " << arg << std::endl; } @@ -646,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 7b58389..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; @@ -69,9 +67,9 @@ void cmGlobalMSYSMakefileGenerator::EnableLanguage( rc = trc; } mf->AddDefinition("MSYS", "1"); - mf->AddDefinition("CMAKE_GENERATOR_CC", gcc.c_str()); - mf->AddDefinition("CMAKE_GENERATOR_CXX", gxx.c_str()); - mf->AddDefinition("CMAKE_GENERATOR_RC", rc.c_str()); + mf->AddDefinition("CMAKE_GENERATOR_CC", gcc); + mf->AddDefinition("CMAKE_GENERATOR_CXX", gxx); + mf->AddDefinition("CMAKE_GENERATOR_RC", rc); this->cmGlobalUnixMakefileGenerator3::EnableLanguage(l, mf, optional); if (!mf->IsSet("CMAKE_AR") && !this->CMakeInstance->GetIsInTryCompile() && diff --git a/Source/cmGlobalMinGWMakefileGenerator.cxx b/Source/cmGlobalMinGWMakefileGenerator.cxx index e218b4b..d9fc505 100644 --- a/Source/cmGlobalMinGWMakefileGenerator.cxx +++ b/Source/cmGlobalMinGWMakefileGenerator.cxx @@ -44,9 +44,9 @@ void cmGlobalMinGWMakefileGenerator::EnableLanguage( if (!trc.empty()) { rc = trc; } - mf->AddDefinition("CMAKE_GENERATOR_CC", gcc.c_str()); - mf->AddDefinition("CMAKE_GENERATOR_CXX", gxx.c_str()); - mf->AddDefinition("CMAKE_GENERATOR_RC", rc.c_str()); + mf->AddDefinition("CMAKE_GENERATOR_CC", gcc); + mf->AddDefinition("CMAKE_GENERATOR_CXX", gxx); + mf->AddDefinition("CMAKE_GENERATOR_RC", rc); this->cmGlobalUnixMakefileGenerator3::EnableLanguage(l, mf, optional); } diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index 2d52356..062eccb 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -9,10 +9,11 @@ #include <algorithm> #include <ctype.h> #include <iterator> -#include <memory> // IWYU pragma: keep #include <sstream> #include <stdio.h> +#include "cm_memory.hxx" + #include "cmAlgorithms.h" #include "cmDocumentationEntry.h" #include "cmFortranParser.h" @@ -31,6 +32,7 @@ #include "cmStateDirectory.h" #include "cmStateSnapshot.h" #include "cmStateTypes.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmTarget.h" #include "cmTargetDepend.h" @@ -381,7 +383,7 @@ void cmGlobalNinjaGenerator::WriteVariable(std::ostream& os, } // Do not add a variable if the value is empty. - std::string val = cmSystemTools::TrimWhitespace(value); + std::string val = cmTrimWhitespace(value); if (val.empty()) { return; } @@ -413,14 +415,6 @@ void cmGlobalNinjaGenerator::WriteDefault(std::ostream& os, cmGlobalNinjaGenerator::cmGlobalNinjaGenerator(cmake* cm) : cmGlobalCommonGenerator(cm) - , UsingGCCOnWindows(false) - , ComputingUnknownDependencies(false) - , PolicyCMP0058(cmPolicies::WARN) - , NinjaSupportsConsolePool(false) - , NinjaSupportsImplicitOuts(false) - , NinjaSupportsManifestRestat(false) - , NinjaSupportsMultilineDepfile(false) - , NinjaSupportsDyndeps(0) { #ifdef _WIN32 cm->GetState()->SetWindowsShell(true); @@ -534,7 +528,7 @@ bool cmGlobalNinjaGenerator::FindMakeProgram(cmMakefile* mf) cmSystemTools::SetFatalErrorOccured(); return false; } - this->NinjaVersion = cmSystemTools::TrimWhitespace(version); + this->NinjaVersion = cmTrimWhitespace(version); this->CheckNinjaFeatures(); } return true; @@ -554,14 +548,22 @@ void cmGlobalNinjaGenerator::CheckNinjaFeatures() this->NinjaSupportsMultilineDepfile = !cmSystemTools::VersionCompare( cmSystemTools::OP_LESS, this->NinjaVersion.c_str(), RequiredNinjaVersionForMultilineDepfile().c_str()); - { + this->NinjaSupportsDyndeps = !cmSystemTools::VersionCompare( + cmSystemTools::OP_LESS, this->NinjaVersion.c_str(), + RequiredNinjaVersionForDyndeps().c_str()); + if (!this->NinjaSupportsDyndeps) { + // The ninja version number is not new enough to have upstream support. // Our ninja branch adds ".dyndep-#" to its version number, // where '#' is a feature-specific version number. Extract it. static std::string const k_DYNDEP_ = ".dyndep-"; std::string::size_type pos = this->NinjaVersion.find(k_DYNDEP_); if (pos != std::string::npos) { const char* fv = &this->NinjaVersion[pos + k_DYNDEP_.size()]; - cmSystemTools::StringToULong(fv, &this->NinjaSupportsDyndeps); + unsigned long dyndep = 0; + cmStrToULong(fv, &dyndep); + if (dyndep == 1) { + this->NinjaSupportsDyndeps = true; + } } } } @@ -569,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; @@ -578,37 +579,25 @@ bool cmGlobalNinjaGenerator::CheckLanguages( bool cmGlobalNinjaGenerator::CheckFortran(cmMakefile* mf) const { - if (this->NinjaSupportsDyndeps == 1) { + if (this->NinjaSupportsDyndeps) { return true; } std::ostringstream e; - if (this->NinjaSupportsDyndeps == 0) { - /* clang-format off */ - e << - "The Ninja generator does not support Fortran using Ninja version\n" - " " + this->NinjaVersion + "\n" - "due to lack of required features. " - "Kitware has implemented the required features but as of this version " - "of CMake they have not been integrated to upstream ninja. " - "Pending integration, Kitware maintains a branch at:\n" - " https://github.com/Kitware/ninja/tree/features-for-fortran#readme\n" - "with the required features. " - "One may build ninja from that branch to get support for Fortran." - ; - /* clang-format on */ - } else { - /* clang-format off */ - e << - "The Ninja generator in this version of CMake does not support Fortran " - "using Ninja version\n" - " " + this->NinjaVersion + "\n" - "because its 'dyndep' feature version is " << - this->NinjaSupportsDyndeps << ". " - "This version of CMake is aware only of 'dyndep' feature version 1." - ; - /* clang-format on */ - } + /* clang-format off */ + e << + "The Ninja generator does not support Fortran using Ninja version\n" + " " + this->NinjaVersion + "\n" + "due to lack of required features. " + "Kitware has implemented the required features and they have been " + "merged to upstream ninja for inclusion in Ninja 1.10 and higher. " + "As of this version of CMake, Ninja 1.10 has not been released. " + "Meanwhile, Kitware maintains a branch of Ninja at:\n" + " https://github.com/Kitware/ninja/tree/features-for-fortran#readme\n" + "with the required features. " + "One may build ninja from that branch to get support for Fortran." + ; + /* clang-format on */ mf->IssueMessage(MessageType::FATAL_ERROR, e.str()); cmSystemTools::SetFatalErrorOccured(); return false; @@ -638,7 +627,9 @@ void cmGlobalNinjaGenerator::EnableLanguage( (mf->GetSafeDefinition("CMAKE_C_COMPILER_ID") == "GNU") || (mf->GetSafeDefinition("CMAKE_CXX_COMPILER_ID") == "GNU") || (mf->GetSafeDefinition("CMAKE_C_COMPILER_ID") == "Clang") || - (mf->GetSafeDefinition("CMAKE_CXX_COMPILER_ID") == "Clang")))) { + (mf->GetSafeDefinition("CMAKE_CXX_COMPILER_ID") == "Clang") || + (mf->GetSafeDefinition("CMAKE_C_COMPILER_ID") == "QCC") || + (mf->GetSafeDefinition("CMAKE_CXX_COMPILER_ID") == "QCC")))) { this->UsingGCCOnWindows = true; } #endif @@ -713,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; } @@ -727,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) { @@ -766,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) { @@ -1323,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; @@ -1357,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; @@ -1466,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()) { @@ -1498,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); @@ -1739,8 +1725,9 @@ int cmcmd_cmake_ninja_depends(std::vector<std::string>::const_iterator argBeg, if (arg_lang == "Fortran") { info = cmcmd_cmake_ninja_depends_fortran(arg_tdi, arg_pp); } else { - cmSystemTools::Error("-E cmake_ninja_depends does not understand the " + - arg_lang + " language"); + cmSystemTools::Error( + cmStrCat("-E cmake_ninja_depends does not understand the ", arg_lang, + " language")); return 1; } @@ -1794,8 +1781,9 @@ std::unique_ptr<cmSourceInfo> cmcmd_cmake_ninja_depends_fortran( cmsys::ifstream tdif(arg_tdi.c_str(), std::ios::in | std::ios::binary); Json::Reader reader; if (!reader.parse(tdif, tdio, false)) { - cmSystemTools::Error("-E cmake_ninja_depends failed to parse " + - arg_tdi + reader.getFormattedErrorMessages()); + cmSystemTools::Error( + cmStrCat("-E cmake_ninja_depends failed to parse ", arg_tdi, + reader.getFormattedErrorMessages())); return nullptr; } } @@ -1874,8 +1862,9 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile( cmsys::ifstream ddif(arg_ddi.c_str(), std::ios::in | std::ios::binary); Json::Reader reader; if (!reader.parse(ddif, ddio, false)) { - cmSystemTools::Error("-E cmake_ninja_dyndep failed to parse " + arg_ddi + - reader.getFormattedErrorMessages()); + cmSystemTools::Error(cmStrCat("-E cmake_ninja_dyndep failed to parse ", + arg_ddi, + reader.getFormattedErrorMessages())); return false; } @@ -1902,14 +1891,14 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile( // Populate the module map with those provided by linked targets first. for (std::string const& linked_target_dir : linked_target_dirs) { std::string const ltmn = - linked_target_dir + "/" + arg_lang + "Modules.json"; + cmStrCat(linked_target_dir, "/", arg_lang, "Modules.json"); Json::Value ltm; cmsys::ifstream ltmf(ltmn.c_str(), std::ios::in | std::ios::binary); Json::Reader reader; if (ltmf && !reader.parse(ltmf, ltm, false)) { - cmSystemTools::Error("-E cmake_ninja_dyndep failed to parse " + - linked_target_dir + - reader.getFormattedErrorMessages()); + cmSystemTools::Error(cmStrCat("-E cmake_ninja_dyndep failed to parse ", + linked_target_dir, + reader.getFormattedErrorMessages())); return false; } if (ltm.isObject()) { @@ -2013,8 +2002,9 @@ int cmcmd_cmake_ninja_dyndep(std::vector<std::string>::const_iterator argBeg, cmsys::ifstream tdif(arg_tdi.c_str(), std::ios::in | std::ios::binary); Json::Reader reader; if (!reader.parse(tdif, tdio, false)) { - cmSystemTools::Error("-E cmake_ninja_dyndep failed to parse " + arg_tdi + - reader.getFormattedErrorMessages()); + cmSystemTools::Error(cmStrCat("-E cmake_ninja_dyndep failed to parse ", + arg_tdi, + reader.getFormattedErrorMessages())); return 1; } } diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h index 15dd404..db64031 100644 --- a/Source/cmGlobalNinjaGenerator.h +++ b/Source/cmGlobalNinjaGenerator.h @@ -7,7 +7,7 @@ #include <iosfwd> #include <map> -#include <memory> // IWYU pragma: keep +#include <memory> #include <set> #include <string> #include <unordered_map> @@ -322,6 +322,7 @@ public: { return "1.9"; } + static std::string RequiredNinjaVersionForDyndeps() { return "1.10"; } bool SupportsConsolePool() const; bool SupportsImplicitOuts() const; bool SupportsManifestRestat() const; @@ -402,7 +403,7 @@ private: /// The set of dependencies to add to the "all" target. cmNinjaDeps AllDependencies; - bool UsingGCCOnWindows; + bool UsingGCCOnWindows = false; /// The set of custom commands we have seen. std::set<cmCustomCommand const*> CustomCommands; @@ -412,8 +413,8 @@ private: /// Whether we are collecting known build outputs and needed /// dependencies to determine unknown dependencies. - bool ComputingUnknownDependencies; - cmPolicies::PolicyStatus PolicyCMP0058; + bool ComputingUnknownDependencies = false; + cmPolicies::PolicyStatus PolicyCMP0058 = cmPolicies::WARN; /// The combined explicit dependencies of custom build commands std::set<std::string> CombinedCustomCommandExplicitDependencies; @@ -435,11 +436,11 @@ private: std::string NinjaCommand; std::string NinjaVersion; - bool NinjaSupportsConsolePool; - bool NinjaSupportsImplicitOuts; - bool NinjaSupportsManifestRestat; - bool NinjaSupportsMultilineDepfile; - unsigned long NinjaSupportsDyndeps; + bool NinjaSupportsConsolePool = false; + bool NinjaSupportsImplicitOuts = false; + bool NinjaSupportsManifestRestat = false; + bool NinjaSupportsMultilineDepfile = false; + bool NinjaSupportsDyndeps = false; private: void InitOutputPathPrefix(); diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx index aa584ad..22c304e 100644 --- a/Source/cmGlobalUnixMakefileGenerator3.cxx +++ b/Source/cmGlobalUnixMakefileGenerator3.cxx @@ -7,6 +7,8 @@ #include <sstream> #include <utility> +#include "cm_memory.hxx" + #include "cmAlgorithms.h" #include "cmDocumentationEntry.h" #include "cmGeneratedFileStream.h" @@ -20,6 +22,7 @@ #include "cmState.h" #include "cmStateDirectory.h" #include "cmStateTypes.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmTargetDepend.h" #include "cmake.h" @@ -105,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; } @@ -144,10 +145,8 @@ void cmGlobalUnixMakefileGenerator3::Generate() pmi.second.WriteProgressVariables(total, current); } for (cmLocalGenerator* lg : this->LocalGenerators) { - std::string markFileName = lg->GetCurrentBinaryDirectory(); - markFileName += "/"; - markFileName += "/CMakeFiles"; - markFileName += "/progress.marks"; + std::string markFileName = + cmStrCat(lg->GetCurrentBinaryDirectory(), "/CMakeFiles/progress.marks"); cmGeneratedFileStream markFile(markFileName); markFile << this->CountProgressMarksInAll(lg) << "\n"; } @@ -195,9 +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"; - makefileName += "/Makefile2"; + cmStrCat(this->GetCMakeInstance()->GetHomeOutputDirectory(), + "/CMakeFiles/Makefile2"); cmGeneratedFileStream makefileStream(makefileName, false, this->GetMakefileEncoding()); if (!makefileStream) { @@ -255,17 +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"; - cmakefileName += "/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 = @@ -317,9 +313,9 @@ void cmGlobalUnixMakefileGenerator3::WriteMainCMakefile() cmakefileStream << " )\n\n"; // Build the path to the cache check file. - std::string check = this->GetCMakeInstance()->GetHomeOutputDirectory(); - check += "/CMakeFiles"; - check += "/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" @@ -349,9 +345,8 @@ void cmGlobalUnixMakefileGenerator3::WriteMainCMakefile() std::string tmpStr; for (cmLocalGenerator* localGen : this->LocalGenerators) { lg = static_cast<cmLocalUnixMakefileGenerator3*>(localGen); - tmpStr = lg->GetCurrentBinaryDirectory(); - tmpStr += "/CMakeFiles"; - tmpStr += "/CMakeDirectoryInformation.cmake"; + tmpStr = cmStrCat(lg->GetCurrentBinaryDirectory(), + "/CMakeFiles/CMakeDirectoryInformation.cmake"); cmakefileStream << " \"" << lg->MaybeConvertToRelativePath(binDir, tmpStr) << "\"\n"; @@ -383,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"; } @@ -399,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. @@ -418,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)); } } @@ -429,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)); } @@ -444,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); @@ -581,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) { @@ -594,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.", @@ -610,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( @@ -657,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)); @@ -679,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 = ""; @@ -695,7 +674,7 @@ void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules2( if (const char* tgtMsg = this->GetCMakeInstance()->GetState()->GetGlobalProperty( "TARGET_MESSAGES")) { - targetMessages = cmSystemTools::IsOn(tgtMsg); + targetMessages = cmIsOn(tgtMsg); } if (targetMessages) { @@ -723,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; @@ -739,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); @@ -754,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)); @@ -774,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( @@ -894,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); } } @@ -939,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); } } @@ -948,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 55374a4..48b17c0 100644 --- a/Source/cmGlobalVisualStudio10Generator.cxx +++ b/Source/cmGlobalVisualStudio10Generator.cxx @@ -325,7 +325,7 @@ bool cmGlobalVisualStudio10Generator::SetGeneratorToolset( bool cmGlobalVisualStudio10Generator::ParseGeneratorToolset( std::string const& ts, cmMakefile* mf) { - std::vector<std::string> const fields = cmSystemTools::tokenize(ts, ","); + std::vector<std::string> const fields = cmTokenize(ts, ","); std::vector<std::string>::const_iterator fi = fields.begin(); if (fi == fields.end()) { return true; @@ -445,7 +445,7 @@ bool cmGlobalVisualStudio10Generator::InitializeSystem(cmMakefile* mf) this->DefaultPlatformName = "Tegra-Android"; this->DefaultPlatformToolset = "Default"; this->NsightTegraVersion = v; - mf->AddDefinition("CMAKE_VS_NsightTegra_VERSION", v.c_str()); + mf->AddDefinition("CMAKE_VS_NsightTegra_VERSION", v); } return true; @@ -659,8 +659,7 @@ bool cmGlobalVisualStudio10Generator::FindMakeProgram(cmMakefile* mf) if (!this->cmGlobalVisualStudio8Generator::FindMakeProgram(mf)) { return false; } - mf->AddDefinition("CMAKE_VS_MSBUILD_COMMAND", - this->GetMSBuildCommand().c_str()); + mf->AddDefinition("CMAKE_VS_MSBUILD_COMMAND", this->GetMSBuildCommand()); return true; } @@ -679,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); @@ -721,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(); @@ -906,8 +905,7 @@ cmGlobalVisualStudio10Generator::GenerateBuildCommand( { std::string slnFile; if (!projectDir.empty()) { - slnFile = projectDir; - slnFile += "/"; + slnFile = cmStrCat(projectDir, '/'); } slnFile += projectName; slnFile += ".sln"; @@ -954,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)) { @@ -1038,14 +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 += "/"; - 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/cmGlobalVisualStudio14Generator.cxx b/Source/cmGlobalVisualStudio14Generator.cxx index 6509b56..cd48474 100644 --- a/Source/cmGlobalVisualStudio14Generator.cxx +++ b/Source/cmGlobalVisualStudio14Generator.cxx @@ -182,7 +182,7 @@ void cmGlobalVisualStudio14Generator::SetWindowsTargetPlatformVersion( mf->DisplayStatus(e.str(), -1); } mf->AddDefinition("CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION", - this->WindowsTargetPlatformVersion.c_str()); + this->WindowsTargetPlatformVersion); } bool cmGlobalVisualStudio14Generator::SelectWindowsStoreToolset( diff --git a/Source/cmGlobalVisualStudio71Generator.cxx b/Source/cmGlobalVisualStudio71Generator.cxx index 8e67fad..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"; @@ -201,7 +199,7 @@ void cmGlobalVisualStudio71Generator::WriteProjectConfigurations( if (target.GetProperty("EXTERNAL_MSPROJECT")) { if (const char* m = target.GetProperty("MAP_IMPORTED_CONFIG_" + cmSystemTools::UpperCase(i))) { - cmSystemTools::ExpandListArgument(m, mapConfig); + cmExpandList(m, mapConfig); if (!mapConfig.empty()) { dstConfig = mapConfig[0].c_str(); } diff --git a/Source/cmGlobalVisualStudio7Generator.cxx b/Source/cmGlobalVisualStudio7Generator.cxx index 8764ee4..26ceedd 100644 --- a/Source/cmGlobalVisualStudio7Generator.cxx +++ b/Source/cmGlobalVisualStudio7Generator.cxx @@ -8,7 +8,9 @@ #include "cmMakefile.h" #include "cmMessageType.h" #include "cmState.h" +#include "cmStringAlgorithms.h" #include "cmUuid.h" +#include "cm_string_view.hxx" #include "cmake.h" #include "cmsys/Encoding.hxx" @@ -64,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; @@ -121,8 +124,7 @@ bool cmGlobalVisualStudio7Generator::FindMakeProgram(cmMakefile* mf) if (!this->cmGlobalVisualStudioGenerator::FindMakeProgram(mf)) { return false; } - mf->AddDefinition("CMAKE_VS_DEVENV_COMMAND", - this->GetDevEnvCommand().c_str()); + mf->AddDefinition("CMAKE_VS_DEVENV_COMMAND", this->GetDevEnvCommand()); return true; } @@ -152,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); @@ -255,7 +258,7 @@ cmLocalGenerator* cmGlobalVisualStudio7Generator::CreateLocalGenerator( return lg; } -#if defined(CMAKE_BUILD_WITH_CMAKE) +#if !defined(CMAKE_BOOTSTRAP) Json::Value cmGlobalVisualStudio7Generator::GetJson() const { Json::Value generator = this->cmGlobalVisualStudioGenerator::GetJson(); @@ -268,7 +271,7 @@ bool cmGlobalVisualStudio7Generator::SetSystemName(std::string const& s, cmMakefile* mf) { mf->AddDefinition("CMAKE_VS_INTEL_Fortran_PROJECT_VERSION", - this->GetIntelProjectVersion().c_str()); + this->GetIntelProjectVersion()); return this->cmGlobalVisualStudioGenerator::SetSystemName(s, mf); } @@ -293,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) { @@ -433,16 +434,15 @@ void cmGlobalVisualStudio7Generator::WriteTargetDepends( void cmGlobalVisualStudio7Generator::WriteFolders(std::ostream& fout) { - const char* prefix = "CMAKE_FOLDER_GUID_"; - const std::string::size_type skip_prefix = strlen(prefix); + cm::string_view const prefix = "CMAKE_FOLDER_GUID_"; std::string guidProjectTypeFolder = "2150E333-8FDC-42A3-9474-1A3956D46DE8"; for (auto const& iter : VisualStudioFolders) { std::string fullName = iter.first; std::string guid = this->GetGUID(fullName); std::replace(fullName.begin(), fullName.end(), '/', '\\'); - if (cmSystemTools::StringStartsWith(fullName.c_str(), prefix)) { - fullName = fullName.substr(skip_prefix); + if (cmHasPrefix(fullName, prefix)) { + fullName = fullName.substr(prefix.size()); } std::string nameOnly = cmSystemTools::GetFilenameName(fullName); @@ -511,16 +511,15 @@ void cmGlobalVisualStudio7Generator::WriteSLNGlobalSections( extensibilityAddInsOverridden = true; } fout << "\tGlobalSection(" << name << ") = " << sectionType << "\n"; - std::vector<std::string> keyValuePairs; - cmSystemTools::ExpandListArgument(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) { const std::string key = - cmSystemTools::TrimWhitespace(itPair.substr(0, posEqual)); + cmTrimWhitespace(itPair.substr(0, posEqual)); const std::string value = - cmSystemTools::TrimWhitespace(itPair.substr(posEqual + 1)); + cmTrimWhitespace(itPair.substr(posEqual + 1)); fout << "\t\t" << key << " = " << value << "\n"; if (key == "SolutionGuid") { addGuid = false; @@ -555,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()); @@ -617,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; @@ -668,8 +664,7 @@ std::set<std::string> cmGlobalVisualStudio7Generator::IsPartOfDefaultBuild( cmGeneratorExpression ge; std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(propertyValue); - if (cmSystemTools::IsOn( - cge->Evaluate(target->GetLocalGenerator(), i))) { + if (cmIsOn(cge->Evaluate(target->GetLocalGenerator(), i))) { activeConfigs.insert(i); } } @@ -685,7 +680,7 @@ std::set<std::string> cmGlobalVisualStudio7Generator::IsPartOfDefaultBuild( for (std::string const& i : configs) { const char* propertyValue = target->GetFeature("EXCLUDE_FROM_DEFAULT_BUILD", i); - if (cmSystemTools::IsOff(propertyValue)) { + if (cmIsOff(propertyValue)) { activeConfigs.insert(i); } } diff --git a/Source/cmGlobalVisualStudio7Generator.h b/Source/cmGlobalVisualStudio7Generator.h index f004afb..9b84732 100644 --- a/Source/cmGlobalVisualStudio7Generator.h +++ b/Source/cmGlobalVisualStudio7Generator.h @@ -23,7 +23,7 @@ public: //! Create a local generator appropriate to this Global Generator cmLocalGenerator* CreateLocalGenerator(cmMakefile* mf) override; -#if defined(CMAKE_BUILD_WITH_CMAKE) +#if !defined(CMAKE_BOOTSTRAP) Json::Value GetJson() const override; #endif diff --git a/Source/cmGlobalVisualStudio8Generator.cxx b/Source/cmGlobalVisualStudio8Generator.cxx index 85ddc85..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); @@ -54,8 +54,7 @@ void cmGlobalVisualStudio8Generator::EnableLanguage( void cmGlobalVisualStudio8Generator::AddPlatformDefinitions(cmMakefile* mf) { if (this->TargetsWindowsCE()) { - mf->AddDefinition("CMAKE_VS_WINCE_VERSION", - this->WindowsCEVersion.c_str()); + mf->AddDefinition("CMAKE_VS_WINCE_VERSION", this->WindowsCEVersion); } } @@ -117,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); } @@ -177,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()); @@ -251,7 +245,7 @@ void cmGlobalVisualStudio8Generator::WriteProjectConfigurations( if (target.GetProperty("EXTERNAL_MSPROJECT")) { if (const char* m = target.GetProperty("MAP_IMPORTED_CONFIG_" + cmSystemTools::UpperCase(i))) { - cmSystemTools::ExpandListArgument(m, mapConfig); + cmExpandList(m, mapConfig); if (!mapConfig.empty()) { dstConfig = mapConfig[0].c_str(); } @@ -300,7 +294,7 @@ bool cmGlobalVisualStudio8Generator::DeployInhibited( cmGeneratorExpression ge; std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(propStr); std::string prop = cge->Evaluate(target.LocalGenerator, config); - rVal = cmSystemTools::IsOn(prop); + rVal = cmIsOn(prop); } return rVal; } diff --git a/Source/cmGlobalVisualStudioGenerator.cxx b/Source/cmGlobalVisualStudioGenerator.cxx index cd0355f..6e0b804 100644 --- a/Source/cmGlobalVisualStudioGenerator.cxx +++ b/Source/cmGlobalVisualStudioGenerator.cxx @@ -57,7 +57,7 @@ void cmGlobalVisualStudioGenerator::EnableLanguage( std::vector<std::string> const& lang, cmMakefile* mf, bool optional) { mf->AddDefinition("CMAKE_VS_PLATFORM_NAME_DEFAULT", - this->DefaultPlatformName.c_str()); + this->DefaultPlatformName); this->cmGlobalGenerator::EnableLanguage(lang, mf, optional); } @@ -69,7 +69,7 @@ bool cmGlobalVisualStudioGenerator::SetGeneratorPlatform(std::string const& p, } else if (this->GetPlatformName() == "Itanium") { mf->AddDefinition("CMAKE_FORCE_IA64", "TRUE"); } - mf->AddDefinition("CMAKE_VS_PLATFORM_NAME", this->GetPlatformName().c_str()); + mf->AddDefinition("CMAKE_VS_PLATFORM_NAME", this->GetPlatformName()); return this->cmGlobalGenerator::SetGeneratorPlatform(p, mf); } @@ -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) { @@ -487,8 +489,8 @@ bool cmGlobalVisualStudioGenerator::FindMakeProgram(cmMakefile* mf) // Visual Studio generators know how to lookup their build tool // directly instead of needing a helper module to do it, so we // do not actually need to put CMAKE_MAKE_PROGRAM into the cache. - if (cmSystemTools::IsOff(mf->GetDefinition("CMAKE_MAKE_PROGRAM"))) { - mf->AddDefinition("CMAKE_MAKE_PROGRAM", this->GetVSMakeProgram().c_str()); + if (cmIsOff(mf->GetDefinition("CMAKE_MAKE_PROGRAM"))) { + mf->AddDefinition("CMAKE_MAKE_PROGRAM", this->GetVSMakeProgram()); } return true; } @@ -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/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index 7c2bcd3..a204fe0 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -5,11 +5,12 @@ #include "cmsys/RegularExpression.hxx" #include <assert.h> #include <iomanip> -#include <memory> // IWYU pragma: keep #include <sstream> #include <stdio.h> #include <string.h> +#include "cm_memory.hxx" + #include "cmAlgorithms.h" #include "cmComputeLinkInformation.h" #include "cmCustomCommand.h" @@ -37,12 +38,12 @@ struct cmLinkImplementation; -#if defined(CMAKE_BUILD_WITH_CMAKE) && defined(__APPLE__) +#if !defined(CMAKE_BOOTSTRAP) && defined(__APPLE__) # define HAVE_APPLICATION_SERVICES # include <ApplicationServices/ApplicationServices.h> #endif -#if defined(CMAKE_BUILD_WITH_CMAKE) +#if !defined(CMAKE_BOOTSTRAP) # include "cmXMLParser.h" // parse the xml file storing the installed version of Xcode on @@ -187,7 +188,7 @@ cmGlobalGenerator* cmGlobalXCodeGenerator::Factory::CreateGlobalGenerator( if (name != GetActualName()) { return nullptr; } -#if defined(CMAKE_BUILD_WITH_CMAKE) +#if !defined(CMAKE_BOOTSTRAP) cmXcodeVersionParser parser; std::string versionFile; { @@ -239,9 +240,8 @@ bool cmGlobalXCodeGenerator::FindMakeProgram(cmMakefile* mf) // The Xcode generator knows how to lookup its build tool // directly instead of needing a helper module to do it, so we // do not actually need to put CMAKE_MAKE_PROGRAM into the cache. - if (cmSystemTools::IsOff(mf->GetDefinition("CMAKE_MAKE_PROGRAM"))) { - mf->AddDefinition("CMAKE_MAKE_PROGRAM", - this->GetXcodeBuildCommand().c_str()); + if (cmIsOff(mf->GetDefinition("CMAKE_MAKE_PROGRAM"))) { + mf->AddDefinition("CMAKE_MAKE_PROGRAM", this->GetXcodeBuildCommand()); } return true; } @@ -282,8 +282,7 @@ bool cmGlobalXCodeGenerator::SetGeneratorToolset(std::string const& ts, } this->GeneratorToolset = ts; if (!this->GeneratorToolset.empty()) { - mf->AddDefinition("CMAKE_XCODE_PLATFORM_TOOLSET", - this->GeneratorToolset.c_str()); + mf->AddDefinition("CMAKE_XCODE_PLATFORM_TOOLSET", this->GeneratorToolset); } return true; } @@ -292,7 +291,7 @@ void cmGlobalXCodeGenerator::EnableLanguage( std::vector<std::string> const& lang, cmMakefile* mf, bool optional) { mf->AddDefinition("XCODE", "1"); - mf->AddDefinition("XCODE_VERSION", this->VersionString.c_str()); + mf->AddDefinition("XCODE_VERSION", this->VersionString); if (!mf->GetDefinition("CMAKE_CONFIGURATION_TYPES")) { mf->AddCacheDefinition( "CMAKE_CONFIGURATION_TYPES", "Debug;Release;MinSizeRel;RelWithDebInfo", @@ -350,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 { @@ -477,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"; } @@ -488,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; } @@ -597,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); @@ -616,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"; @@ -882,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; - cmSystemTools::ExpandListArgument(extraFileAttributes, attributes); + std::vector<std::string> attributes = cmExpandedList(extraFileAttributes); // Store the attributes. for (const auto& attribute : attributes) { @@ -901,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); } } @@ -1399,13 +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 += "/"; - 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"; @@ -1418,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( @@ -1462,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); @@ -1637,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, @@ -1654,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")); } @@ -1668,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; @@ -1732,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"; } @@ -1775,8 +1750,7 @@ void cmGlobalXCodeGenerator::AddPositionIndependentLinkAttribute( } buildSettings->AddAttribute( - "LD_NO_PIE", - this->CreateString(cmSystemTools::IsOn(PICValue) ? "NO" : "YES")); + "LD_NO_PIE", this->CreateString(cmIsOn(PICValue) ? "NO" : "YES")); } void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt, @@ -1883,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); } @@ -2136,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); @@ -2483,20 +2456,16 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateUtilityTarget( std::string cmGlobalXCodeGenerator::AddConfigurations(cmXCodeObject* target, cmGeneratorTarget* gtgt) { - std::vector<std::string> const configVector = - cmSystemTools::ExpandedListArgument( - this->CurrentMakefile->GetRequiredDefinition( - "CMAKE_CONFIGURATION_TYPES")); + std::vector<std::string> const configVector = cmExpandedList( + this->CurrentMakefile->GetRequiredDefinition("CMAKE_CONFIGURATION_TYPES")); cmXCodeObject* configlist = this->CreateObject(cmXCodeObject::XCConfigurationList); 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)); @@ -2624,9 +2593,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); } @@ -2663,8 +2630,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); @@ -2719,9 +2685,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); } } @@ -2886,8 +2850,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()); } @@ -2929,12 +2893,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()) { @@ -2946,8 +2908,7 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateOrGetPBXGroup( if (it != this->TargetGroup.end()) { tgroup = it->second; } else { - std::vector<std::string> tgt_folders = - cmSystemTools::tokenize(target, "/"); + std::vector<std::string> tgt_folders = cmTokenize(target, "/"); std::string curr_tgt_folder; for (std::vector<std::string>::size_type i = 0; i < tgt_folders.size(); i++) { @@ -2979,10 +2940,8 @@ 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 += "/"; - for (auto const& folder : - cmSystemTools::tokenize(sg->GetFullName(), "\\")) { + std::string curr_folder = cmStrCat(target, '/'); + for (auto const& folder : cmTokenize(sg->GetFullName(), "\\")) { curr_folder += folder; std::map<std::string, cmXCodeObject*>::iterator i_folder = this->GroupNameMap.find(curr_folder); @@ -2994,7 +2953,7 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateOrGetPBXGroup( } else { tgroup = i_folder->second; } - curr_folder = curr_folder + "\\"; + curr_folder += "\\"; } return tgroup; } @@ -3046,8 +3005,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())); @@ -3098,10 +3056,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")); @@ -3150,8 +3106,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) { @@ -3208,15 +3163,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; } @@ -3226,8 +3175,7 @@ void cmGlobalXCodeGenerator::ComputeArchitectures(cmMakefile* mf) const char* osxArch = mf->GetDefinition("CMAKE_OSX_ARCHITECTURES"); const char* sysroot = mf->GetDefinition("CMAKE_OSX_SYSROOT"); if (osxArch && sysroot) { - cmSystemTools::ExpandListArgument(std::string(osxArch), - this->Architectures); + cmExpandList(std::string(osxArch), this->Architectures); } if (this->Architectures.empty()) { @@ -3342,12 +3290,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; @@ -3364,10 +3310,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"; @@ -3395,10 +3339,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); @@ -3472,12 +3414,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); @@ -3583,9 +3525,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; @@ -3607,9 +3547,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; @@ -3629,8 +3567,7 @@ void cmGlobalXCodeGenerator::AppendDefines(BuildObjectListOrString& defs, } // Expand the list of definitions. - std::vector<std::string> defines; - cmSystemTools::ExpandListArgument(defines_list, defines); + std::vector<std::string> defines = cmExpandedList(defines_list); // Store the definitions in the string. this->AppendDefines(defs, defines, dflag); @@ -3644,8 +3581,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; @@ -3706,11 +3642,9 @@ void cmGlobalXCodeGenerator::AppendFlag(std::string& flags, std::string cmGlobalXCodeGenerator::ComputeInfoPListLocation( cmGeneratorTarget* target) { - std::string plist = target->GetLocalGenerator()->GetCurrentBinaryDirectory(); - plist += "/CMakeFiles"; - plist += "/"; - plist += target->GetName(); - plist += ".dir/Info.plist"; + std::string plist = + cmStrCat(target->GetLocalGenerator()->GetCurrentBinaryDirectory(), + "/CMakeFiles/", target->GetName(), ".dir/Info.plist"); return plist; } @@ -3744,7 +3678,7 @@ bool cmGlobalXCodeGenerator::UseEffectivePlatformName(cmMakefile* mf) const return mf->PlatformIsAppleEmbedded(); } - return cmSystemTools::IsOn(epnValue); + return cmIsOn(epnValue); } bool cmGlobalXCodeGenerator::ShouldStripResourcePath(cmMakefile*) const @@ -3757,10 +3691,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 a75d8a9..9b58f61 100644 --- a/Source/cmGraphVizWriter.cxx +++ b/Source/cmGraphVizWriter.cxx @@ -4,7 +4,7 @@ #include <cstddef> #include <iostream> -#include <memory> // IWYU pragma: keep +#include <memory> #include <sstream> #include <utility> @@ -15,6 +15,7 @@ #include "cmMakefile.h" #include "cmState.h" #include "cmStateSnapshot.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmTarget.h" #include "cmake.h" @@ -73,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"); @@ -233,9 +235,8 @@ void cmGraphVizWriter::ReadSettings( this->TargetsToIgnoreRegex.clear(); if (!ignoreTargetsRegexes.empty()) { - std::vector<std::string> ignoreTargetsRegExVector; - cmSystemTools::ExpandListArgument(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/cmIDEOptions.cxx b/Source/cmIDEOptions.cxx index 7b992d7..e80aa8e 100644 --- a/Source/cmIDEOptions.cxx +++ b/Source/cmIDEOptions.cxx @@ -8,7 +8,7 @@ #include "cmAlgorithms.h" #include "cmIDEFlagTable.h" -#include "cmSystemTools.h" +#include "cmStringAlgorithms.h" cmIDEOptions::cmIDEOptions() { @@ -166,7 +166,7 @@ void cmIDEOptions::AddDefines(std::string const& defines) { if (!defines.empty()) { // Expand the list of definitions. - cmSystemTools::ExpandListArgument(defines, this->Defines); + cmExpandList(defines, this->Defines); } } void cmIDEOptions::AddDefines(const std::vector<std::string>& defines) @@ -188,7 +188,7 @@ void cmIDEOptions::AddIncludes(std::string const& includes) { if (!includes.empty()) { // Expand the list of includes. - cmSystemTools::ExpandListArgument(includes, this->Includes); + cmExpandList(includes, this->Includes); } } void cmIDEOptions::AddIncludes(const std::vector<std::string>& includes) diff --git a/Source/cmIfCommand.cxx b/Source/cmIfCommand.cxx index d1f8f58..f719041 100644 --- a/Source/cmIfCommand.cxx +++ b/Source/cmIfCommand.cxx @@ -2,16 +2,24 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmIfCommand.h" +#include "cm_memory.hxx" +#include "cm_static_string_view.hxx" +#include "cm_string_view.hxx" + #include "cmConditionEvaluator.h" #include "cmExecutionStatus.h" #include "cmExpandedCommandArgument.h" +#include "cmFunctionBlocker.h" +#include "cmListFileCache.h" #include "cmMakefile.h" #include "cmMessageType.h" #include "cmOutputConverter.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmake.h" -#include <memory> // IWYU pragma: keep +#include <string> +#include <utility> static std::string cmIfCommandError( std::vector<cmExpandedCommandArgument> const& args) @@ -25,192 +33,178 @@ static std::string cmIfCommandError( return err; } -//========================================================================= -bool cmIfFunctionBlocker::IsFunctionBlocked(const cmListFileFunction& lff, - cmMakefile& mf, - cmExecutionStatus& inStatus) +class cmIfFunctionBlocker : public cmFunctionBlocker +{ +public: + cm::string_view StartCommandName() const override { return "if"_s; } + cm::string_view EndCommandName() const override { return "endif"_s; } + + bool ArgumentsMatch(cmListFileFunction const& lff, + cmMakefile&) const override; + + bool Replay(std::vector<cmListFileFunction> functions, + cmExecutionStatus& inStatus) override; + + std::vector<cmListFileArgument> Args; + bool IsBlocking; + bool HasRun = false; + bool ElseSeen = false; +}; + +bool cmIfFunctionBlocker::ArgumentsMatch(cmListFileFunction const& lff, + cmMakefile&) const { - // we start by recording all the functions - if (lff.Name.Lower == "if") { - this->ScopeDepth++; - } else if (lff.Name.Lower == "endif") { - this->ScopeDepth--; - // if this is the endif for this if statement, then start executing - if (!this->ScopeDepth) { - // Remove the function blocker for this scope or bail. - std::unique_ptr<cmFunctionBlocker> fb( - mf.RemoveFunctionBlocker(this, lff)); - if (!fb) { - return false; + return lff.Arguments.empty() || lff.Arguments == this->Args; +} + +bool cmIfFunctionBlocker::Replay(std::vector<cmListFileFunction> functions, + cmExecutionStatus& inStatus) +{ + cmMakefile& mf = inStatus.GetMakefile(); + // execute the functions for the true parts of the if statement + int scopeDepth = 0; + for (cmListFileFunction const& func : functions) { + // keep track of scope depth + if (func.Name.Lower == "if") { + scopeDepth++; + } + if (func.Name.Lower == "endif") { + scopeDepth--; + } + // watch for our state change + if (scopeDepth == 0 && func.Name.Lower == "else") { + + if (this->ElseSeen) { + cmListFileBacktrace bt = mf.GetBacktrace(func); + mf.GetCMakeInstance()->IssueMessage( + MessageType::FATAL_ERROR, + "A duplicate ELSE command was found inside an IF block.", bt); + cmSystemTools::SetFatalErrorOccured(); + return true; } - // execute the functions for the true parts of the if statement - cmExecutionStatus status; - int scopeDepth = 0; - for (cmListFileFunction const& func : this->Functions) { - // keep track of scope depth - if (func.Name.Lower == "if") { - scopeDepth++; - } - if (func.Name.Lower == "endif") { - scopeDepth--; + this->IsBlocking = this->HasRun; + this->HasRun = true; + this->ElseSeen = true; + + // if trace is enabled, print a (trivially) evaluated "else" + // statement + if (!this->IsBlocking && mf.GetCMakeInstance()->GetTrace()) { + mf.PrintCommandTrace(func); + } + } else if (scopeDepth == 0 && func.Name.Lower == "elseif") { + if (this->ElseSeen) { + cmListFileBacktrace bt = mf.GetBacktrace(func); + mf.GetCMakeInstance()->IssueMessage( + MessageType::FATAL_ERROR, + "An ELSEIF command was found after an ELSE command.", bt); + cmSystemTools::SetFatalErrorOccured(); + return true; + } + + if (this->HasRun) { + this->IsBlocking = true; + } else { + // if trace is enabled, print the evaluated "elseif" statement + if (mf.GetCMakeInstance()->GetTrace()) { + mf.PrintCommandTrace(func); } - // watch for our state change - if (scopeDepth == 0 && func.Name.Lower == "else") { - - if (this->ElseSeen) { - cmListFileBacktrace bt = mf.GetBacktrace(func); - mf.GetCMakeInstance()->IssueMessage( - MessageType::FATAL_ERROR, - "A duplicate ELSE command was found inside an IF block.", bt); - cmSystemTools::SetFatalErrorOccured(); - return true; - } - this->IsBlocking = this->HasRun; - this->HasRun = true; - this->ElseSeen = true; + std::string errorString; - // if trace is enabled, print a (trivially) evaluated "else" - // statement - if (!this->IsBlocking && mf.GetCMakeInstance()->GetTrace()) { - mf.PrintCommandTrace(func); - } - } else if (scopeDepth == 0 && func.Name.Lower == "elseif") { - if (this->ElseSeen) { - cmListFileBacktrace bt = mf.GetBacktrace(func); - mf.GetCMakeInstance()->IssueMessage( - MessageType::FATAL_ERROR, - "An ELSEIF command was found after an ELSE command.", bt); + std::vector<cmExpandedCommandArgument> expandedArguments; + mf.ExpandArguments(func.Arguments, expandedArguments); + + MessageType messType; + + cmListFileContext conditionContext = + cmListFileContext::FromCommandContext( + func, this->GetStartingContext().FilePath); + + cmConditionEvaluator conditionEvaluator(mf, conditionContext, + mf.GetBacktrace(func)); + + bool isTrue = + conditionEvaluator.IsTrue(expandedArguments, errorString, messType); + + if (!errorString.empty()) { + std::string err = + cmStrCat(cmIfCommandError(expandedArguments), errorString); + cmListFileBacktrace bt = mf.GetBacktrace(func); + mf.GetCMakeInstance()->IssueMessage(messType, err, bt); + if (messType == MessageType::FATAL_ERROR) { cmSystemTools::SetFatalErrorOccured(); return true; } - - if (this->HasRun) { - this->IsBlocking = true; - } else { - // if trace is enabled, print the evaluated "elseif" statement - if (mf.GetCMakeInstance()->GetTrace()) { - mf.PrintCommandTrace(func); - } - - std::string errorString; - - std::vector<cmExpandedCommandArgument> expandedArguments; - mf.ExpandArguments(func.Arguments, expandedArguments); - - MessageType messType; - - cmListFileContext conditionContext = - cmListFileContext::FromCommandContext( - func, this->GetStartingContext().FilePath); - - cmConditionEvaluator conditionEvaluator(mf, conditionContext, - mf.GetBacktrace(func)); - - bool isTrue = conditionEvaluator.IsTrue(expandedArguments, - errorString, messType); - - if (!errorString.empty()) { - std::string err = cmIfCommandError(expandedArguments); - err += errorString; - cmListFileBacktrace bt = mf.GetBacktrace(func); - mf.GetCMakeInstance()->IssueMessage(messType, err, bt); - if (messType == MessageType::FATAL_ERROR) { - cmSystemTools::SetFatalErrorOccured(); - return true; - } - } - - if (isTrue) { - this->IsBlocking = false; - this->HasRun = true; - } - } } - // should we execute? - else if (!this->IsBlocking) { - status.Clear(); - mf.ExecuteCommand(func, status); - if (status.GetReturnInvoked()) { - inStatus.SetReturnInvoked(); - return true; - } - if (status.GetBreakInvoked()) { - inStatus.SetBreakInvoked(); - return true; - } - if (status.GetContinueInvoked()) { - inStatus.SetContinueInvoked(); - return true; - } + if (isTrue) { + this->IsBlocking = false; + this->HasRun = true; } } - return true; } - } - - // record the command - this->Functions.push_back(lff); - // always return true - return true; -} - -//========================================================================= -bool cmIfFunctionBlocker::ShouldRemove(const cmListFileFunction& lff, - cmMakefile&) -{ - if (lff.Name.Lower == "endif") { - // if the endif has arguments, then make sure - // they match the arguments of the matching if - if (lff.Arguments.empty() || lff.Arguments == this->Args) { - return true; + // should we execute? + else if (!this->IsBlocking) { + cmExecutionStatus status(mf); + mf.ExecuteCommand(func, status); + if (status.GetReturnInvoked()) { + inStatus.SetReturnInvoked(); + return true; + } + if (status.GetBreakInvoked()) { + inStatus.SetBreakInvoked(); + return true; + } + if (status.GetContinueInvoked()) { + inStatus.SetContinueInvoked(); + return true; + } } } - - return false; + return true; } //========================================================================= -bool cmIfCommand::InvokeInitialPass( - const std::vector<cmListFileArgument>& args, cmExecutionStatus&) +bool cmIfCommand(std::vector<cmListFileArgument> const& args, + cmExecutionStatus& inStatus) { + cmMakefile& makefile = inStatus.GetMakefile(); std::string errorString; std::vector<cmExpandedCommandArgument> expandedArguments; - this->Makefile->ExpandArguments(args, expandedArguments); + makefile.ExpandArguments(args, expandedArguments); MessageType status; cmConditionEvaluator conditionEvaluator( - *(this->Makefile), this->Makefile->GetExecutionContext(), - this->Makefile->GetBacktrace()); + makefile, makefile.GetExecutionContext(), makefile.GetBacktrace()); bool isTrue = 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) { - this->Makefile->IssueMessage(MessageType::FATAL_ERROR, err); + makefile.IssueMessage(MessageType::FATAL_ERROR, err); cmSystemTools::SetFatalErrorOccured(); return true; } - this->Makefile->IssueMessage(status, err); + makefile.IssueMessage(status, err); } - cmIfFunctionBlocker* f = new cmIfFunctionBlocker(); - // if is isn't true block the commands - f->ScopeDepth = 1; - f->IsBlocking = !isTrue; - if (isTrue) { - f->HasRun = true; + { + auto fb = cm::make_unique<cmIfFunctionBlocker>(); + // if is isn't true block the commands + fb->IsBlocking = !isTrue; + if (isTrue) { + fb->HasRun = true; + } + fb->Args = args; + makefile.AddFunctionBlocker(std::move(fb)); } - f->Args = args; - this->Makefile->AddFunctionBlocker(f); return true; } diff --git a/Source/cmIfCommand.h b/Source/cmIfCommand.h index d34ed02..820ffa4 100644 --- a/Source/cmIfCommand.h +++ b/Source/cmIfCommand.h @@ -5,61 +5,13 @@ #include "cmConfigure.h" // IWYU pragma: keep -#include <string> #include <vector> -#include "cmCommand.h" -#include "cmFunctionBlocker.h" -#include "cmListFileCache.h" - class cmExecutionStatus; -class cmExpandedCommandArgument; -class cmMakefile; - -class cmIfFunctionBlocker : public cmFunctionBlocker -{ -public: - bool IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile& mf, - cmExecutionStatus&) override; - bool ShouldRemove(const cmListFileFunction& lff, cmMakefile& mf) override; - - std::vector<cmListFileArgument> Args; - std::vector<cmListFileFunction> Functions; - bool IsBlocking; - bool HasRun = false; - bool ElseSeen = false; - unsigned int ScopeDepth = 0; -}; +struct cmListFileArgument; /// Starts an if block -class cmIfCommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - cmCommand* Clone() override { return new cmIfCommand; } - - /** - * This overrides the default InvokeInitialPass implementation. - * It records the arguments before expansion. - */ - bool InvokeInitialPass(const std::vector<cmListFileArgument>& args, - cmExecutionStatus&) override; - - /** - * This is called when the command is first encountered in - * the CMakeLists.txt file. - */ - bool InitialPass(std::vector<std::string> const&, - cmExecutionStatus&) override - { - return false; - } - - // Filter the given variable definition based on policy CMP0054. - static const char* GetDefinitionIfUnquoted( - const cmMakefile* mf, cmExpandedCommandArgument const& argument); -}; +bool cmIfCommand(std::vector<cmListFileArgument> const& args, + cmExecutionStatus& status); #endif 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 3b843b2..b0dd779 100644 --- a/Source/cmIncludeCommand.h +++ b/Source/cmIncludeCommand.h @@ -8,30 +8,15 @@ #include <string> #include <vector> -#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. - */ - cmCommand* Clone() override { return new 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 62e2abd..876bd95 100644 --- a/Source/cmIncludeDirectoryCommand.cxx +++ b/Source/cmIncludeDirectoryCommand.cxx @@ -9,6 +9,7 @@ #include "cmAlgorithms.h" #include "cmGeneratorExpression.h" #include "cmMakefile.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" class cmExecutionStatus; @@ -116,14 +117,13 @@ void cmIncludeDirectoryCommand::NormalizeInclude(std::string& inc) return; } - if (!cmSystemTools::IsOff(inc)) { + if (!cmIsOff(inc)) { cmSystemTools::ConvertToUnixSlashes(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/cmIncludeDirectoryCommand.h b/Source/cmIncludeDirectoryCommand.h index 01d98db..4df94eb 100644 --- a/Source/cmIncludeDirectoryCommand.h +++ b/Source/cmIncludeDirectoryCommand.h @@ -8,6 +8,8 @@ #include <string> #include <vector> +#include "cm_memory.hxx" + #include "cmCommand.h" class cmExecutionStatus; @@ -24,7 +26,10 @@ public: /** * This is a virtual constructor for the command. */ - cmCommand* Clone() override { return new cmIncludeDirectoryCommand; } + std::unique_ptr<cmCommand> Clone() override + { + return cm::make_unique<cmIncludeDirectoryCommand>(); + } /** * This is called when the command is first encountered in diff --git a/Source/cmIncludeExternalMSProjectCommand.h b/Source/cmIncludeExternalMSProjectCommand.h index 945acdc..9f76576 100644 --- a/Source/cmIncludeExternalMSProjectCommand.h +++ b/Source/cmIncludeExternalMSProjectCommand.h @@ -8,6 +8,8 @@ #include <string> #include <vector> +#include "cm_memory.hxx" + #include "cmCommand.h" class cmExecutionStatus; @@ -25,7 +27,10 @@ public: /** * This is a virtual constructor for the command. */ - cmCommand* Clone() override { return new cmIncludeExternalMSProjectCommand; } + std::unique_ptr<cmCommand> Clone() override + { + return cm::make_unique<cmIncludeExternalMSProjectCommand>(); + } /** * This is called when the command is first encountered in diff --git a/Source/cmIncludeGuardCommand.cxx b/Source/cmIncludeGuardCommand.cxx index 505b07c..ccb4496 100644 --- a/Source/cmIncludeGuardCommand.cxx +++ b/Source/cmIncludeGuardCommand.cxx @@ -21,7 +21,7 @@ enum IncludeGuardScope std::string GetIncludeGuardVariableName(std::string const& filePath) { std::string result = "__INCGUARD_"; -#ifdef CMAKE_BUILD_WITH_CMAKE +#ifndef CMAKE_BOOTSTRAP result += cmSystemTools::ComputeStringMD5(filePath); #else result += cmSystemTools::MakeCidentifier(filePath); @@ -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: @@ -85,7 +85,7 @@ bool cmIncludeGuardCommand::InitialPass(std::vector<std::string> const& args, status.SetReturnInvoked(); return true; } - mf->AddDefinition(includeGuardVar, true); + mf->AddDefinitionBool(includeGuardVar, true); break; case DIRECTORY: if (CheckIncludeGuardIsSet(mf, includeGuardVar)) { diff --git a/Source/cmIncludeGuardCommand.h b/Source/cmIncludeGuardCommand.h index eaad9b8..b86b760 100644 --- a/Source/cmIncludeGuardCommand.h +++ b/Source/cmIncludeGuardCommand.h @@ -8,30 +8,15 @@ #include <string> #include <vector> -#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. - */ - cmCommand* Clone() override { return new 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/cmIncludeRegularExpressionCommand.h b/Source/cmIncludeRegularExpressionCommand.h index 8da991d..1723c8b 100644 --- a/Source/cmIncludeRegularExpressionCommand.h +++ b/Source/cmIncludeRegularExpressionCommand.h @@ -8,6 +8,8 @@ #include <string> #include <vector> +#include "cm_memory.hxx" + #include "cmCommand.h" class cmExecutionStatus; @@ -24,7 +26,10 @@ public: /** * This is a virtual constructor for the command. */ - cmCommand* Clone() override { return new cmIncludeRegularExpressionCommand; } + std::unique_ptr<cmCommand> Clone() override + { + return cm::make_unique<cmIncludeRegularExpressionCommand>(); + } /** * This is called when the command is first encountered in diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx index c9e6923..9a78c49 100644 --- a/Source/cmInstallCommand.cxx +++ b/Source/cmInstallCommand.cxx @@ -9,7 +9,6 @@ #include <stddef.h> #include <utility> -#include "cmAlgorithms.h" #include "cmArgumentParser.h" #include "cmExportSet.h" #include "cmExportSetMap.h" @@ -27,6 +26,7 @@ #include "cmMessageType.h" #include "cmPolicies.h" #include "cmStateTypes.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmTarget.h" #include "cmTargetExport.h" @@ -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; } @@ -391,10 +388,6 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) return true; } - // Check whether this is a DLL platform. - bool dll_platform = - !this->Makefile->GetSafeDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX").empty(); - for (std::string const& tgt : targetList) { if (this->Makefile->IsAlias(tgt)) { @@ -474,7 +467,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) // Shared libraries are handled differently on DLL and non-DLL // platforms. All windows platforms are DLL platforms including // cygwin. Currently no other platform is a DLL platform. - if (dll_platform) { + if (target.IsDLLPlatform()) { // When in namelink only mode skip all libraries on Windows. if (namelinkMode == cmInstallTargetGenerator::NamelinkModeOnly) { continue; @@ -643,7 +636,8 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) // On DLL platforms an executable may also have an import // library. Install it to the archive destination if it // exists. - if (dll_platform && !archiveArgs.GetDestination().empty() && + if ((target.IsDLLPlatform() || target.IsAIX()) && + !archiveArgs.GetDestination().empty() && target.IsExecutableWithExports()) { // The import library uses the ARCHIVE properties. archiveGenerator = CreateInstallTargetGenerator( @@ -675,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; - cmSystemTools::ExpandListArgument(files, relFiles); + std::vector<std::string> relFiles = cmExpandedList(files); std::vector<std::string> absFiles; if (!this->MakeFilesFullPath("PRIVATE_HEADER", relFiles, absFiles)) { return false; @@ -690,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; - cmSystemTools::ExpandListArgument(files, relFiles); + std::vector<std::string> relFiles = cmExpandedList(files); std::vector<std::string> absFiles; if (!this->MakeFilesFullPath("PUBLIC_HEADER", relFiles, absFiles)) { return false; @@ -705,8 +697,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) files = target.GetProperty("RESOURCE"); if ((files) && (*files)) { - std::vector<std::string> relFiles; - cmSystemTools::ExpandListArgument(files, relFiles); + std::vector<std::string> relFiles = cmExpandedList(files); std::vector<std::string> absFiles; if (!this->MakeFilesFullPath("RESOURCE", relFiles, absFiles)) { return false; @@ -1126,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. @@ -1271,7 +1261,7 @@ bool cmInstallCommand::HandleDirectoryMode( bool cmInstallCommand::HandleExportAndroidMKMode( std::vector<std::string> const& args) { -#ifdef CMAKE_BUILD_WITH_CMAKE +#ifndef CMAKE_BOOTSTRAP // This is the EXPORT mode. cmInstallCommandArguments ica(this->DefaultComponentName); @@ -1427,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; @@ -1485,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/cmInstallCommand.h b/Source/cmInstallCommand.h index 202c438..28bf443 100644 --- a/Source/cmInstallCommand.h +++ b/Source/cmInstallCommand.h @@ -8,6 +8,8 @@ #include <string> #include <vector> +#include "cm_memory.hxx" + #include "cmCommand.h" class cmExecutionStatus; @@ -25,7 +27,10 @@ public: /** * This is a virtual constructor for the command. */ - cmCommand* Clone() override { return new cmInstallCommand; } + std::unique_ptr<cmCommand> Clone() override + { + return cm::make_unique<cmInstallCommand>(); + } /** * This is called when the command is first encountered in diff --git a/Source/cmInstallDirectoryGenerator.cxx b/Source/cmInstallDirectoryGenerator.cxx index 14288f6..1d8210c 100644 --- a/Source/cmInstallDirectoryGenerator.cxx +++ b/Source/cmInstallDirectoryGenerator.cxx @@ -6,9 +6,10 @@ #include "cmInstallType.h" #include "cmLocalGenerator.h" #include "cmMakefile.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" -#include <memory> // IWYU pragma: keep +#include <memory> cmInstallDirectoryGenerator::cmInstallDirectoryGenerator( std::vector<std::string> const& dirs, const char* dest, @@ -66,15 +67,14 @@ void cmInstallDirectoryGenerator::GenerateScriptForConfig( cmGeneratorExpression ge; for (std::string const& d : this->Directories) { std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(d); - cmSystemTools::ExpandListArgument( - cge->Evaluate(this->LocalGenerator, config), dirs); + cmExpandList(cge->Evaluate(this->LocalGenerator, config), dirs); } // Make sure all dirs have absolute paths. cmMakefile const& mf = *this->LocalGenerator->GetMakefile(); for (std::string& d : dirs) { if (!cmSystemTools::FileIsFullPath(d)) { - d = mf.GetCurrentSourceDirectory() + "/" + d; + d = cmStrCat(mf.GetCurrentSourceDirectory(), "/", d); } } 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 f5bedab..0b3617b 100644 --- a/Source/cmInstallExportGenerator.cxx +++ b/Source/cmInstallExportGenerator.cxx @@ -7,13 +7,14 @@ #include <sstream> #include <utility> -#ifdef CMAKE_BUILD_WITH_CMAKE +#ifndef CMAKE_BOOTSTRAP # include "cmExportInstallAndroidMKGenerator.h" #endif #include "cmExportInstallFileGenerator.h" #include "cmExportSet.h" #include "cmInstallType.h" #include "cmLocalGenerator.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" cmInstallExportGenerator::cmInstallExportGenerator( @@ -31,7 +32,7 @@ cmInstallExportGenerator::cmInstallExportGenerator( , LocalGenerator(nullptr) { if (android) { -#ifdef CMAKE_BUILD_WITH_CMAKE +#ifndef CMAKE_BOOTSTRAP this->EFGen = new cmExportInstallAndroidMKGenerator(this); #endif } else { @@ -56,9 +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"; - this->TempDir += "/Export"; + this->TempDir = cmStrCat(this->LocalGenerator->GetCurrentBinaryDirectory(), + "/CMakeFiles/Export"); if (this->Destination.empty()) { return; } @@ -136,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()); @@ -186,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(); @@ -218,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 efbcb67..11687a8 100644 --- a/Source/cmInstallFilesCommand.cxx +++ b/Source/cmInstallFilesCommand.cxx @@ -2,18 +2,24 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmInstallFilesCommand.h" -#include "cmAlgorithms.h" #include "cmGeneratorExpression.h" #include "cmGlobalGenerator.h" #include "cmInstallFilesGenerator.h" #include "cmInstallGenerator.h" #include "cmMakefile.h" #include "cmRange.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" class cmExecutionStatus; -// cmExecutableCommand +static std::string FindInstallSource(cmMakefile& makefile, const char* name); +static void CreateInstallGenerator(cmMakefile& makefile, + std::string const& dest, + std::vector<std::string> const& files); +static void FinalAction(cmMakefile& makefile, std::string const& dest, + std::vector<std::string> const& args); + bool cmInstallFilesCommand::InitialPass(std::vector<std::string> const& args, cmExecutionStatus&) { @@ -25,18 +31,20 @@ bool cmInstallFilesCommand::InitialPass(std::vector<std::string> const& args, // Enable the install target. this->Makefile->GetGlobalGenerator()->EnableInstallTarget(); - this->Destination = args[0]; + std::string const& dest = args[0]; if ((args.size() > 1) && (args[1] == "FILES")) { - this->IsFilesForm = true; + std::vector<std::string> files; for (std::string const& arg : cmMakeRange(args).advance(2)) { // Find the source location for each file listed. - this->Files.push_back(this->FindInstallSource(arg.c_str())); + files.push_back(FindInstallSource(*this->Makefile, arg.c_str())); } - this->CreateInstallGenerator(); + CreateInstallGenerator(*this->Makefile, dest, files); } else { - this->IsFilesForm = false; - cmAppend(this->FinalArgs, args.begin() + 1, args.end()); + std::vector<std::string> finalArgs(args.begin() + 1, args.end()); + this->Makefile->AddFinalAction([dest, finalArgs](cmMakefile& makefile) { + FinalAction(makefile, dest, finalArgs); + }); } this->Makefile->GetGlobalGenerator()->AddInstallComponent( @@ -45,23 +53,20 @@ bool cmInstallFilesCommand::InitialPass(std::vector<std::string> const& args, return true; } -void cmInstallFilesCommand::FinalPass() +static void FinalAction(cmMakefile& makefile, std::string const& dest, + std::vector<std::string> const& args) { - // No final pass for "FILES" form of arguments. - if (this->IsFilesForm) { - return; - } - std::string testf; - std::string const& ext = this->FinalArgs[0]; + std::string const& ext = args[0]; + std::vector<std::string> installFiles; // two different options - if (this->FinalArgs.size() > 1) { + if (args.size() > 1) { // now put the files into the list - std::vector<std::string>::iterator s = this->FinalArgs.begin(); + std::vector<std::string>::const_iterator s = args.begin(); ++s; // for each argument, get the files - for (; s != this->FinalArgs.end(); ++s) { + for (; s != args.end(); ++s) { // replace any variables std::string const& temps = *s; if (!cmSystemTools::GetFilenamePath(temps).empty()) { @@ -72,30 +77,31 @@ void cmInstallFilesCommand::FinalPass() } // add to the result - this->Files.push_back(this->FindInstallSource(testf.c_str())); + installFiles.push_back(FindInstallSource(makefile, testf.c_str())); } } else // reg exp list { std::vector<std::string> files; - std::string const& regex = this->FinalArgs[0]; - cmSystemTools::Glob(this->Makefile->GetCurrentSourceDirectory(), regex, - files); + std::string const& regex = args[0]; + cmSystemTools::Glob(makefile.GetCurrentSourceDirectory(), regex, files); std::vector<std::string>::iterator s = files.begin(); // for each argument, get the files for (; s != files.end(); ++s) { - this->Files.push_back(this->FindInstallSource(s->c_str())); + installFiles.push_back(FindInstallSource(makefile, s->c_str())); } } - this->CreateInstallGenerator(); + CreateInstallGenerator(makefile, dest, installFiles); } -void cmInstallFilesCommand::CreateInstallGenerator() const +static void CreateInstallGenerator(cmMakefile& makefile, + std::string const& dest, + std::vector<std::string> const& files) { // Construct the destination. This command always installs under // the prefix. We skip the leading slash given by the user. - std::string destination = this->Destination.substr(1); + std::string destination = dest.substr(1); cmSystemTools::ConvertToUnixSlashes(destination); if (destination.empty()) { destination = "."; @@ -106,12 +112,12 @@ void cmInstallFilesCommand::CreateInstallGenerator() const const char* no_rename = ""; bool no_exclude_from_all = false; std::string no_component = - this->Makefile->GetSafeDefinition("CMAKE_INSTALL_DEFAULT_COMPONENT_NAME"); + makefile.GetSafeDefinition("CMAKE_INSTALL_DEFAULT_COMPONENT_NAME"); std::vector<std::string> no_configurations; cmInstallGenerator::MessageLevel message = - cmInstallGenerator::SelectMessageLevel(this->Makefile); - this->Makefile->AddInstallGenerator(new cmInstallFilesGenerator( - this->Files, destination.c_str(), false, no_permissions, no_configurations, + cmInstallGenerator::SelectMessageLevel(&makefile); + makefile.AddInstallGenerator(new cmInstallFilesGenerator( + files, destination.c_str(), false, no_permissions, no_configurations, no_component.c_str(), message, no_exclude_from_all, no_rename)); } @@ -121,7 +127,7 @@ void cmInstallFilesCommand::CreateInstallGenerator() const * present in the build tree. If a full path is given, it is just * returned. */ -std::string cmInstallFilesCommand::FindInstallSource(const char* name) const +static std::string FindInstallSource(cmMakefile& makefile, const char* name) { if (cmSystemTools::FileIsFullPath(name) || cmGeneratorExpression::Find(name) == 0) { @@ -130,12 +136,8 @@ std::string cmInstallFilesCommand::FindInstallSource(const char* name) const } // This is a relative path. - std::string tb = this->Makefile->GetCurrentBinaryDirectory(); - tb += "/"; - tb += name; - std::string ts = this->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/cmInstallFilesCommand.h b/Source/cmInstallFilesCommand.h index a52f45e..f9b84fd 100644 --- a/Source/cmInstallFilesCommand.h +++ b/Source/cmInstallFilesCommand.h @@ -8,6 +8,8 @@ #include <string> #include <vector> +#include "cm_memory.hxx" + #include "cmCommand.h" class cmExecutionStatus; @@ -24,7 +26,10 @@ public: /** * This is a virtual constructor for the command. */ - cmCommand* Clone() override { return new cmInstallFilesCommand; } + std::unique_ptr<cmCommand> Clone() override + { + return cm::make_unique<cmInstallFilesCommand>(); + } /** * This is called when the command is first encountered in @@ -32,25 +37,6 @@ public: */ bool InitialPass(std::vector<std::string> const& args, cmExecutionStatus& status) override; - - /** - * This is called at the end after all the information - * specified by the command is accumulated. Most commands do - * not implement this method. At this point, reading and - * writing to the cache can be done. - */ - void FinalPass() override; - bool HasFinalPass() const override { return !this->IsFilesForm; } - -protected: - void CreateInstallGenerator() const; - std::string FindInstallSource(const char* name) const; - -private: - std::vector<std::string> FinalArgs; - bool IsFilesForm = false; - std::string Destination; - std::vector<std::string> Files; }; #endif diff --git a/Source/cmInstallFilesGenerator.cxx b/Source/cmInstallFilesGenerator.cxx index 2ed9f73..c4048d4 100644 --- a/Source/cmInstallFilesGenerator.cxx +++ b/Source/cmInstallFilesGenerator.cxx @@ -4,9 +4,9 @@ #include "cmGeneratorExpression.h" #include "cmInstallType.h" -#include "cmSystemTools.h" +#include "cmStringAlgorithms.h" -#include <memory> // IWYU pragma: keep +#include <memory> class cmLocalGenerator; @@ -85,8 +85,7 @@ void cmInstallFilesGenerator::GenerateScriptForConfig( cmGeneratorExpression ge; for (std::string const& f : this->Files) { std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(f); - cmSystemTools::ExpandListArgument( - cge->Evaluate(this->LocalGenerator, config), files); + cmExpandList(cge->Evaluate(this->LocalGenerator, config), files); } this->AddFilesInstallRule(os, config, indent, files); } diff --git a/Source/cmInstallProgramsCommand.cxx b/Source/cmInstallProgramsCommand.cxx index a58f875..3eca0e0 100644 --- a/Source/cmInstallProgramsCommand.cxx +++ b/Source/cmInstallProgramsCommand.cxx @@ -2,16 +2,20 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmInstallProgramsCommand.h" -#include "cmAlgorithms.h" #include "cmGeneratorExpression.h" #include "cmGlobalGenerator.h" #include "cmInstallFilesGenerator.h" #include "cmInstallGenerator.h" #include "cmMakefile.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" class cmExecutionStatus; +static void FinalAction(cmMakefile& makefile, std::string const& dest, + std::vector<std::string> const& args); +static std::string FindInstallSource(cmMakefile& makefile, const char* name); + // cmExecutableCommand bool cmInstallProgramsCommand::InitialPass( std::vector<std::string> const& args, cmExecutionStatus&) @@ -24,51 +28,55 @@ bool cmInstallProgramsCommand::InitialPass( // Enable the install target. this->Makefile->GetGlobalGenerator()->EnableInstallTarget(); - this->Destination = args[0]; - - cmAppend(this->FinalArgs, args.begin() + 1, args.end()); - this->Makefile->GetGlobalGenerator()->AddInstallComponent( this->Makefile->GetSafeDefinition("CMAKE_INSTALL_DEFAULT_COMPONENT_NAME")); + std::string const& dest = args[0]; + std::vector<std::string> const finalArgs(args.begin() + 1, args.end()); + this->Makefile->AddFinalAction([dest, finalArgs](cmMakefile& makefile) { + FinalAction(makefile, dest, finalArgs); + }); return true; } -void cmInstallProgramsCommand::FinalPass() +static void FinalAction(cmMakefile& makefile, std::string const& dest, + std::vector<std::string> const& args) { bool files_mode = false; - if (!this->FinalArgs.empty() && this->FinalArgs[0] == "FILES") { + if (!args.empty() && args[0] == "FILES") { files_mode = true; } + std::vector<std::string> files; + // two different options - if (this->FinalArgs.size() > 1 || files_mode) { + if (args.size() > 1 || files_mode) { // for each argument, get the programs - std::vector<std::string>::iterator s = this->FinalArgs.begin(); + std::vector<std::string>::const_iterator s = args.begin(); if (files_mode) { // Skip the FILES argument in files mode. ++s; } - for (; s != this->FinalArgs.end(); ++s) { + for (; s != args.end(); ++s) { // add to the result - this->Files.push_back(this->FindInstallSource(s->c_str())); + files.push_back(FindInstallSource(makefile, s->c_str())); } } else // reg exp list { std::vector<std::string> programs; - cmSystemTools::Glob(this->Makefile->GetCurrentSourceDirectory(), - this->FinalArgs[0], programs); + cmSystemTools::Glob(makefile.GetCurrentSourceDirectory(), args[0], + programs); std::vector<std::string>::iterator s = programs.begin(); // for each argument, get the programs for (; s != programs.end(); ++s) { - this->Files.push_back(this->FindInstallSource(s->c_str())); + files.push_back(FindInstallSource(makefile, s->c_str())); } } // Construct the destination. This command always installs under // the prefix. We skip the leading slash given by the user. - std::string destination = this->Destination.substr(1); + std::string destination = dest.substr(1); cmSystemTools::ConvertToUnixSlashes(destination); if (destination.empty()) { destination = "."; @@ -79,12 +87,12 @@ void cmInstallProgramsCommand::FinalPass() const char* no_rename = ""; bool no_exclude_from_all = false; std::string no_component = - this->Makefile->GetSafeDefinition("CMAKE_INSTALL_DEFAULT_COMPONENT_NAME"); + makefile.GetSafeDefinition("CMAKE_INSTALL_DEFAULT_COMPONENT_NAME"); std::vector<std::string> no_configurations; cmInstallGenerator::MessageLevel message = - cmInstallGenerator::SelectMessageLevel(this->Makefile); - this->Makefile->AddInstallGenerator(new cmInstallFilesGenerator( - this->Files, destination.c_str(), true, no_permissions, no_configurations, + cmInstallGenerator::SelectMessageLevel(&makefile); + makefile.AddInstallGenerator(new cmInstallFilesGenerator( + files, destination.c_str(), true, no_permissions, no_configurations, no_component.c_str(), message, no_exclude_from_all, no_rename)); } @@ -94,7 +102,7 @@ void cmInstallProgramsCommand::FinalPass() * present in the build tree. If a full path is given, it is just * returned. */ -std::string cmInstallProgramsCommand::FindInstallSource(const char* name) const +static std::string FindInstallSource(cmMakefile& makefile, const char* name) { if (cmSystemTools::FileIsFullPath(name) || cmGeneratorExpression::Find(name) == 0) { @@ -103,12 +111,8 @@ std::string cmInstallProgramsCommand::FindInstallSource(const char* name) const } // This is a relative path. - std::string tb = this->Makefile->GetCurrentBinaryDirectory(); - tb += "/"; - tb += name; - std::string ts = this->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.h b/Source/cmInstallProgramsCommand.h index 5c705eb..ccd621d 100644 --- a/Source/cmInstallProgramsCommand.h +++ b/Source/cmInstallProgramsCommand.h @@ -8,6 +8,8 @@ #include <string> #include <vector> +#include "cm_memory.hxx" + #include "cmCommand.h" class cmExecutionStatus; @@ -24,7 +26,10 @@ public: /** * This is a virtual constructor for the command. */ - cmCommand* Clone() override { return new cmInstallProgramsCommand; } + std::unique_ptr<cmCommand> Clone() override + { + return cm::make_unique<cmInstallProgramsCommand>(); + } /** * This is called when the command is first encountered in @@ -32,24 +37,6 @@ public: */ bool InitialPass(std::vector<std::string> const& args, cmExecutionStatus& status) override; - - /** - * This is called at the end after all the information - * specified by the command is accumulated. Most commands do - * not implement this method. At this point, reading and - * writing to the cache can be done. - */ - void FinalPass() override; - - bool HasFinalPass() const override { return true; } - -protected: - std::string FindInstallSource(const char* name) const; - -private: - std::vector<std::string> FinalArgs; - std::string Destination; - std::vector<std::string> Files; }; #endif diff --git a/Source/cmInstallScriptGenerator.cxx b/Source/cmInstallScriptGenerator.cxx index 5832d27..b7b7817 100644 --- a/Source/cmInstallScriptGenerator.cxx +++ b/Source/cmInstallScriptGenerator.cxx @@ -2,6 +2,7 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmInstallScriptGenerator.h" +#include <memory> #include <ostream> #include <vector> diff --git a/Source/cmInstallTargetGenerator.cxx b/Source/cmInstallTargetGenerator.cxx index 7c5a55b..7bbef35 100644 --- a/Source/cmInstallTargetGenerator.cxx +++ b/Source/cmInstallTargetGenerator.cxx @@ -4,6 +4,7 @@ #include <assert.h> #include <map> +#include <memory> #include <set> #include <sstream> #include <utility> @@ -16,7 +17,10 @@ #include "cmLocalGenerator.h" #include "cmMakefile.h" #include "cmMessageType.h" +#include "cmOutputConverter.h" +#include "cmPolicies.h" #include "cmStateTypes.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmTarget.h" #include "cmake.h" @@ -83,20 +87,18 @@ void cmInstallTargetGenerator::GenerateScriptForConfig( std::string fromDirConfig; if (this->Target->NeedRelinkBeforeInstall(config)) { fromDirConfig = - this->Target->GetLocalGenerator()->GetCurrentBinaryDirectory(); - fromDirConfig += "/CMakeFiles"; - fromDirConfig += "/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; @@ -366,7 +368,7 @@ void cmInstallTargetGenerator::GetInstallObjectNames( { this->Target->GetTargetObjectNames(config, objects); for (std::string& o : objects) { - o = computeInstallObjectDir(this->Target, config) + "/" + o; + o = cmStrCat(computeInstallObjectDir(this->Target, config), "/", o); } } @@ -590,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)); } } @@ -632,17 +634,34 @@ void cmInstallTargetGenerator::AddRPathCheckRule( return; } - // Get the install RPATH from the link information. - std::string newRpath = cli->GetChrpathString(); - // Write a rule to remove the installed file if its rpath is not the // new rpath. This is needed for existing build/install trees when // the installed rpath changes but the file is not rebuilt. - /* clang-format off */ os << indent << "file(RPATH_CHECK\n" - << indent << " FILE \"" << toDestDirPath << "\"\n" - << indent << " RPATH \"" << newRpath << "\")\n"; - /* clang-format on */ + << indent << " FILE \"" << toDestDirPath << "\"\n"; + + // CMP0095: ``RPATH`` entries are properly escaped in the intermediary + // CMake install script. + switch (this->Target->GetPolicyStatusCMP0095()) { + case cmPolicies::WARN: + // No author warning needed here, we warn later in + // cmInstallTargetGenerator::AddChrpathPatchRule(). + CM_FALLTHROUGH; + case cmPolicies::OLD: { + // Get the install RPATH from the link information. + std::string newRpath = cli->GetChrpathString(); + os << indent << " RPATH \"" << newRpath << "\")\n"; + break; + } + default: { + // Get the install RPATH from the link information and + // escape any CMake syntax in the install RPATH. + std::string escapedNewRpath = + cmOutputConverter::EscapeForCMake(cli->GetChrpathString()); + os << indent << " RPATH " << escapedNewRpath << ")\n"; + break; + } + } } void cmInstallTargetGenerator::AddChrpathPatchRule( @@ -668,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); @@ -731,11 +751,34 @@ void cmInstallTargetGenerator::AddChrpathPatchRule( return; } + // Escape any CMake syntax in the RPATHs. + std::string escapedOldRpath = cmOutputConverter::EscapeForCMake(oldRpath); + std::string escapedNewRpath = cmOutputConverter::EscapeForCMake(newRpath); + // Write a rule to run chrpath to set the install-tree RPATH os << indent << "file(RPATH_CHANGE\n" << indent << " FILE \"" << toDestDirPath << "\"\n" - << indent << " OLD_RPATH \"" << oldRpath << "\"\n" - << indent << " NEW_RPATH \"" << newRpath << "\")\n"; + << indent << " OLD_RPATH " << escapedOldRpath << "\n"; + + // CMP0095: ``RPATH`` entries are properly escaped in the intermediary + // CMake install script. + switch (this->Target->GetPolicyStatusCMP0095()) { + case cmPolicies::WARN: + this->IssueCMP0095Warning(newRpath); + CM_FALLTHROUGH; + case cmPolicies::OLD: + os << indent << " NEW_RPATH \"" << newRpath << "\""; + break; + default: + os << indent << " NEW_RPATH " << escapedNewRpath; + break; + } + + if (this->Target->GetPropertyAsBool("INSTALL_REMOVE_ENVIRONMENT_RPATH")) { + os << "\n" << indent << " INSTALL_REMOVE_ENVIRONMENT_RPATH)\n"; + } else { + os << indent << ")\n"; + } } } @@ -838,3 +881,26 @@ void cmInstallTargetGenerator::AddUniversalInstallRule( << "\"" << this->Target->Target->GetName() << "\" " << "\"" << toDestDirPath << "\")\n"; } + +void cmInstallTargetGenerator::IssueCMP0095Warning( + const std::string& unescapedRpath) +{ + // Reduce warning noise to cases where used RPATHs may actually be affected + // by CMP0095. This filter is meant to skip warnings in cases when + // non-curly-braces syntax (e.g. $ORIGIN) or no keyword is used which has + // worked already before CMP0095. We intend to issue a warning in all cases + // with curly-braces syntax, even if the workaround of double-escaping is in + // place, since we deprecate the need for it with CMP0095. + const bool potentially_affected(unescapedRpath.find("${") != + std::string::npos); + + if (potentially_affected) { + std::ostringstream w; + w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0095) << "\n"; + w << "RPATH entries for target '" << this->Target->GetName() << "' " + << "will not be escaped in the intermediary " + << "cmake_install.cmake script."; + this->Target->GetGlobalGenerator()->GetCMakeInstance()->IssueMessage( + MessageType::AUTHOR_WARNING, w.str(), this->GetBacktrace()); + } +} diff --git a/Source/cmInstallTargetGenerator.h b/Source/cmInstallTargetGenerator.h index ed3ab52..9ccad63 100644 --- a/Source/cmInstallTargetGenerator.h +++ b/Source/cmInstallTargetGenerator.h @@ -104,6 +104,7 @@ protected: const std::string& toDestDirPath); void AddUniversalInstallRule(std::ostream& os, Indent indent, const std::string& toDestDirPath); + void IssueCMP0095Warning(const std::string& unescapedRpath); std::string TargetName; cmGeneratorTarget* Target; diff --git a/Source/cmInstallTargetsCommand.h b/Source/cmInstallTargetsCommand.h index 9950fb7..55e69ba 100644 --- a/Source/cmInstallTargetsCommand.h +++ b/Source/cmInstallTargetsCommand.h @@ -8,6 +8,8 @@ #include <string> #include <vector> +#include "cm_memory.hxx" + #include "cmCommand.h" class cmExecutionStatus; @@ -25,7 +27,10 @@ public: /** * This is a virtual constructor for the command. */ - cmCommand* Clone() override { return new cmInstallTargetsCommand; } + std::unique_ptr<cmCommand> Clone() override + { + return cm::make_unique<cmInstallTargetsCommand>(); + } /** * This is called when the command is first encountered in diff --git a/Source/cmInstalledFile.cxx b/Source/cmInstalledFile.cxx index 537b4ec..1e6c385 100644 --- a/Source/cmInstalledFile.cxx +++ b/Source/cmInstalledFile.cxx @@ -5,7 +5,7 @@ #include "cmAlgorithms.h" #include "cmListFileCache.h" #include "cmMakefile.h" -#include "cmSystemTools.h" +#include "cmStringAlgorithms.h" #include <utility> @@ -97,7 +97,7 @@ bool cmInstalledFile::GetPropertyAsBool(const std::string& prop) const { std::string value; bool isSet = this->GetProperty(prop, value); - return isSet && cmSystemTools::IsOn(value); + return isSet && cmIsOn(value); } void cmInstalledFile::GetPropertyAsList(const std::string& prop, @@ -107,5 +107,5 @@ void cmInstalledFile::GetPropertyAsList(const std::string& prop, this->GetProperty(prop, value); list.clear(); - cmSystemTools::ExpandListArgument(value, list); + cmExpandList(value, list); } diff --git a/Source/cmInstalledFile.h b/Source/cmInstalledFile.h index b7d602e..eb827be 100644 --- a/Source/cmInstalledFile.h +++ b/Source/cmInstalledFile.h @@ -8,7 +8,7 @@ #include "cmGeneratorExpression.h" #include <map> -#include <memory> // IWYU pragma: keep +#include <memory> #include <string> #include <vector> diff --git a/Source/cmJsonObjects.cxx b/Source/cmJsonObjects.cxx index 636a8e1..b8eed13 100644 --- a/Source/cmJsonObjects.cxx +++ b/Source/cmJsonObjects.cxx @@ -14,13 +14,13 @@ #include "cmLinkLineComputer.h" #include "cmLocalGenerator.h" #include "cmMakefile.h" -#include "cmProperty.h" #include "cmPropertyMap.h" #include "cmSourceFile.h" #include "cmState.h" #include "cmStateDirectory.h" #include "cmStateSnapshot.h" #include "cmStateTypes.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmTarget.h" #include "cmTest.h" @@ -32,6 +32,7 @@ #include <functional> #include <limits> #include <map> +#include <memory> #include <set> #include <string> #include <unordered_map> @@ -363,12 +364,12 @@ static Json::Value DumpCTestInfo(cmLocalGenerator* lg, cmTest* testInfo, // Build up the list of properties that may have been specified Json::Value properties = Json::arrayValue; - for (auto& prop : testInfo->GetProperties()) { + for (auto& prop : testInfo->GetProperties().GetList()) { Json::Value entry = Json::objectValue; entry[kKEY_KEY] = prop.first; // Remove config variables from the value too. - auto cge_value = ge.Parse(prop.second.GetValue()); + auto cge_value = ge.Parse(prop.second); const std::string& processed_value = cge_value->Evaluate(lg, config); entry[kVALUE_KEY] = processed_value; properties.append(entry); @@ -500,9 +501,9 @@ static Json::Value DumpTarget(cmGeneratorTarget* target, if (!dest.empty() && cmSystemTools::FileIsFullPath(dest)) { installPath = dest; } else { - std::string installPrefix = - target->Makefile->GetSafeDefinition("CMAKE_INSTALL_PREFIX"); - installPath = installPrefix + '/' + dest; + installPath = cmStrCat( + target->Makefile->GetSafeDefinition("CMAKE_INSTALL_PREFIX"), '/', + dest); } installPaths.append(installPath); @@ -516,9 +517,11 @@ static Json::Value DumpTarget(cmGeneratorTarget* target, Json::Value artifacts = Json::arrayValue; artifacts.append( target->GetFullPath(config, cmStateEnums::RuntimeBinaryArtifact)); - if (target->IsDLLPlatform()) { + if (target->HasImportLibrary(config)) { artifacts.append( target->GetFullPath(config, cmStateEnums::ImportLibraryArtifact)); + } + if (target->IsDLLPlatform()) { const cmGeneratorTarget::OutputInfo* output = target->GetOutputInfo(config); if (output && !output->PdbDir.empty()) { @@ -539,19 +542,19 @@ static Json::Value DumpTarget(cmGeneratorTarget* target, lg->GetTargetFlags(&linkLineComputer, config, linkLibs, linkLanguageFlags, linkFlags, frameworkPath, linkPath, target); - linkLibs = cmSystemTools::TrimWhitespace(linkLibs); - linkFlags = cmSystemTools::TrimWhitespace(linkFlags); - linkLanguageFlags = cmSystemTools::TrimWhitespace(linkLanguageFlags); - frameworkPath = cmSystemTools::TrimWhitespace(frameworkPath); - linkPath = cmSystemTools::TrimWhitespace(linkPath); + linkLibs = cmTrimWhitespace(linkLibs); + linkFlags = cmTrimWhitespace(linkFlags); + linkLanguageFlags = cmTrimWhitespace(linkLanguageFlags); + frameworkPath = cmTrimWhitespace(frameworkPath); + linkPath = cmTrimWhitespace(linkPath); - if (!cmSystemTools::TrimWhitespace(linkLibs).empty()) { + if (!cmTrimWhitespace(linkLibs).empty()) { result[kLINK_LIBRARIES_KEY] = linkLibs; } - if (!cmSystemTools::TrimWhitespace(linkFlags).empty()) { + if (!cmTrimWhitespace(linkFlags).empty()) { result[kLINK_FLAGS_KEY] = linkFlags; } - if (!cmSystemTools::TrimWhitespace(linkLanguageFlags).empty()) { + if (!cmTrimWhitespace(linkLanguageFlags).empty()) { result[kLINK_LANGUAGE_FLAGS_KEY] = linkLanguageFlags; } if (!frameworkPath.empty()) { diff --git a/Source/cmLDConfigLDConfigTool.cxx b/Source/cmLDConfigLDConfigTool.cxx new file mode 100644 index 0000000..b68dbbd --- /dev/null +++ b/Source/cmLDConfigLDConfigTool.cxx @@ -0,0 +1,70 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ + +#include "cmLDConfigLDConfigTool.h" +#include "cmMakefile.h" +#include "cmRuntimeDependencyArchive.h" +#include "cmStringAlgorithms.h" +#include "cmSystemTools.h" +#include "cmUVProcessChain.h" + +#include "cmsys/RegularExpression.hxx" + +#include <istream> +#include <string> +#include <vector> + +cmLDConfigLDConfigTool::cmLDConfigLDConfigTool( + cmRuntimeDependencyArchive* archive) + : cmLDConfigTool(archive) +{ +} + +bool cmLDConfigLDConfigTool::GetLDConfigPaths(std::vector<std::string>& paths) +{ + std::string ldConfigPath = + this->Archive->GetMakefile()->GetSafeDefinition("CMAKE_LDCONFIG_COMMAND"); + if (ldConfigPath.empty()) { + ldConfigPath = cmSystemTools::FindProgram( + "ldconfig", { "/sbin", "/usr/sbin", "/usr/local/sbin" }); + if (ldConfigPath.empty()) { + this->Archive->SetError("Could not find ldconfig"); + return false; + } + } + + 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. + + cmUVProcessChainBuilder builder; + builder.SetBuiltinStream(cmUVProcessChainBuilder::Stream_OUTPUT) + .AddCommand(ldConfigCommand); + auto process = builder.Start(); + if (!process.Valid()) { + this->Archive->SetError("Failed to start ldconfig process"); + return false; + } + + std::string line; + static const cmsys::RegularExpression regex("^([^\t:]*):"); + while (std::getline(*process.OutputStream(), line)) { + cmsys::RegularExpressionMatch match; + if (regex.find(line.c_str(), match)) { + paths.push_back(match.match(1)); + } + } + + if (!process.Wait()) { + this->Archive->SetError("Failed to wait on ldconfig process"); + return false; + } + auto status = process.GetStatus(); + if (!status[0] || status[0]->ExitStatus != 0) { + this->Archive->SetError("Failed to run ldconfig"); + return false; + } + + return true; +} diff --git a/Source/cmLDConfigLDConfigTool.h b/Source/cmLDConfigLDConfigTool.h new file mode 100644 index 0000000..d945a9b --- /dev/null +++ b/Source/cmLDConfigLDConfigTool.h @@ -0,0 +1,22 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ + +#ifndef cmLDConfigLDConfigTool_h +#define cmLDConfigLDConfigTool_h + +#include "cmLDConfigTool.h" + +#include <string> +#include <vector> + +class cmRuntimeDependencyArchive; + +class cmLDConfigLDConfigTool : public cmLDConfigTool +{ +public: + cmLDConfigLDConfigTool(cmRuntimeDependencyArchive* archive); + + bool GetLDConfigPaths(std::vector<std::string>& paths) override; +}; + +#endif diff --git a/Source/cmLDConfigTool.cxx b/Source/cmLDConfigTool.cxx new file mode 100644 index 0000000..8d5d563 --- /dev/null +++ b/Source/cmLDConfigTool.cxx @@ -0,0 +1,9 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ + +#include "cmLDConfigTool.h" + +cmLDConfigTool::cmLDConfigTool(cmRuntimeDependencyArchive* archive) + : Archive(archive) +{ +} diff --git a/Source/cmLDConfigTool.h b/Source/cmLDConfigTool.h new file mode 100644 index 0000000..c816562 --- /dev/null +++ b/Source/cmLDConfigTool.h @@ -0,0 +1,24 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ + +#ifndef cmLDConfigTool_h +#define cmLDConfigTool_h + +#include <string> +#include <vector> + +class cmRuntimeDependencyArchive; + +class cmLDConfigTool +{ +public: + cmLDConfigTool(cmRuntimeDependencyArchive* archive); + virtual ~cmLDConfigTool() = default; + + virtual bool GetLDConfigPaths(std::vector<std::string>& paths) = 0; + +protected: + cmRuntimeDependencyArchive* Archive; +}; + +#endif diff --git a/Source/cmLinkDirectoriesCommand.cxx b/Source/cmLinkDirectoriesCommand.cxx index 7850977..57b69c8 100644 --- a/Source/cmLinkDirectoriesCommand.cxx +++ b/Source/cmLinkDirectoriesCommand.cxx @@ -4,11 +4,11 @@ #include <sstream> -#include "cmAlgorithms.h" #include "cmGeneratorExpression.h" #include "cmMakefile.h" #include "cmMessageType.h" #include "cmPolicies.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" class cmExecutionStatus; @@ -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/cmLinkDirectoriesCommand.h b/Source/cmLinkDirectoriesCommand.h index ae4fb7f..1a439de 100644 --- a/Source/cmLinkDirectoriesCommand.h +++ b/Source/cmLinkDirectoriesCommand.h @@ -8,6 +8,8 @@ #include <string> #include <vector> +#include "cm_memory.hxx" + #include "cmCommand.h" class cmExecutionStatus; @@ -26,7 +28,10 @@ public: /** * This is a virtual constructor for the command. */ - cmCommand* Clone() override { return new cmLinkDirectoriesCommand; } + std::unique_ptr<cmCommand> Clone() override + { + return cm::make_unique<cmLinkDirectoriesCommand>(); + } /** * This is called when the command is first encountered in diff --git a/Source/cmLinkItem.h b/Source/cmLinkItem.h index 5b635b5..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" @@ -58,6 +58,9 @@ struct cmLinkInterfaceLibraries { // Libraries listed in the interface. std::vector<cmLinkItem> Libraries; + + // Whether the list depends on a genex referencing the head target. + bool HadHeadSensitiveCondition = false; }; struct cmLinkInterface : public cmLinkInterfaceLibraries @@ -84,8 +87,7 @@ struct cmOptionalLinkInterface : public cmLinkInterface bool LibrariesDone = false; bool AllDone = false; bool Exists = false; - bool HadHeadSensitiveCondition = false; - const char* ExplicitLibraries = nullptr; + bool Explicit = false; }; struct cmHeadToLinkInterfaceMap @@ -118,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/cmLinkLibrariesCommand.h b/Source/cmLinkLibrariesCommand.h index af25fba..484ab0a 100644 --- a/Source/cmLinkLibrariesCommand.h +++ b/Source/cmLinkLibrariesCommand.h @@ -8,6 +8,8 @@ #include <string> #include <vector> +#include "cm_memory.hxx" + #include "cmCommand.h" class cmExecutionStatus; @@ -25,7 +27,10 @@ public: /** * This is a virtual constructor for the command. */ - cmCommand* Clone() override { return new cmLinkLibrariesCommand; } + std::unique_ptr<cmCommand> Clone() override + { + return cm::make_unique<cmLinkLibrariesCommand>(); + } /** * This is called when the command is first encountered in diff --git a/Source/cmLinkLineComputer.cxx b/Source/cmLinkLineComputer.cxx index 469faca..5e3c790 100644 --- a/Source/cmLinkLineComputer.cxx +++ b/Source/cmLinkLineComputer.cxx @@ -11,6 +11,7 @@ #include "cmOutputConverter.h" #include "cmStateDirectory.h" #include "cmStateTypes.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" cmLinkLineComputer::cmLinkLineComputer(cmOutputConverter* outputConverter, @@ -63,6 +64,7 @@ std::string cmLinkLineComputer::ComputeLinkLibs(cmComputeLinkInformation& cli) continue; } if (item.IsPath) { + linkLibs += cli.GetLibLinkFileFlag(); linkLibs += this->ConvertToOutputFormat(this->ConvertToLinkReference(item.Value)); } else { @@ -110,21 +112,21 @@ std::string cmLinkLineComputer::ComputeLinkPath( if (target->GetType() == cmStateEnums::STATIC_LIBRARY || target->GetType() == cmStateEnums::SHARED_LIBRARY) { cmStateEnums::ArtifactType type = cmStateEnums::RuntimeBinaryArtifact; - if (target->GetType() == cmStateEnums::SHARED_LIBRARY && - target->IsDLLPlatform()) { + if (target->HasImportLibrary(cli.GetConfig())) { type = cmStateEnums::ImportLibraryArtifact; } - linkPath += " " + libPathFlag + - item.Target->GetDirectory(cli.GetConfig(), type) + - libPathTerminator + " "; + linkPath += cmStrCat(" ", libPathFlag, + item.Target->GetDirectory(cli.GetConfig(), type), + libPathTerminator, " "); } } } for (std::string const& libDir : cli.GetDirectories()) { - linkPath += " " + libPathFlag + this->ConvertToOutputForExisting(libDir) + - libPathTerminator + " "; + linkPath += + cmStrCat(" ", libPathFlag, this->ConvertToOutputForExisting(libDir), + libPathTerminator, " "); } return linkPath; diff --git a/Source/cmLinkLineDeviceComputer.cxx b/Source/cmLinkLineDeviceComputer.cxx index 8d2add6..96af388 100644 --- a/Source/cmLinkLineDeviceComputer.cxx +++ b/Source/cmLinkLineDeviceComputer.cxx @@ -3,21 +3,20 @@ #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" #include "cmLocalGenerator.h" +#include "cmMakefile.h" #include "cmStateDirectory.h" #include "cmStateSnapshot.h" #include "cmStateTypes.h" -#include "cmSystemTools.h" +#include "cmStringAlgorithms.h" class cmOutputConverter; @@ -156,16 +155,20 @@ bool requireDeviceLinking(cmGeneratorTarget& target, cmLocalGenerator& lg, return false; } + if (!lg.GetMakefile()->IsOn("CMAKE_CUDA_COMPILER_HAS_DEVICE_LINK_PHASE")) { + return false; + } + if (const char* resolveDeviceSymbols = target.GetProperty("CUDA_RESOLVE_DEVICE_SYMBOLS")) { // If CUDA_RESOLVE_DEVICE_SYMBOLS has been explicitly set we need // to honor the value no matter what it is. - return cmSystemTools::IsOn(resolveDeviceSymbols); + return cmIsOn(resolveDeviceSymbols); } if (const char* separableCompilation = target.GetProperty("CUDA_SEPARABLE_COMPILATION")) { - if (cmSystemTools::IsOn(separableCompilation)) { + if (cmIsOn(separableCompilation)) { bool doDeviceLinking = false; switch (target.GetType()) { case cmStateEnums::SHARED_LIBRARY: @@ -182,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 1b01ea2..91dea58 100644 --- a/Source/cmListCommand.cxx +++ b/Source/cmListCommand.cxx @@ -13,89 +13,35 @@ #include <stdio.h> #include <stdlib.h> // required for atoi #include <utility> +#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" #include "cmPolicies.h" #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; } @@ -103,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 @@ -115,25 +61,24 @@ bool cmListCommand::GetList(std::vector<std::string>& list, return true; } // expand the variable into a list - cmSystemTools::ExpandListArgument(listString, list, true); + 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 // ExpandListArgument without the true which will remove // empty values list.clear(); - cmSystemTools::ExpandListArgument(listString, list); - std::string warn = cmPolicies::GetPolicyWarning(cmPolicies::CMP0007); - warn += " List has value = ["; - warn += listString; - warn += "]."; - this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, warn); + cmExpandList(listString, list); + std::string warn = + cmStrCat(cmPolicies::GetPolicyWarning(cmPolicies::CMP0007), + " List has value = [", listString, "]."); + makefile.IssueMessage(MessageType::AUTHOR_WARNING, warn); return true; } case cmPolicies::OLD: @@ -141,13 +86,13 @@ bool cmListCommand::GetList(std::vector<std::string>& list, // ExpandListArgument without the true which will remove // empty values list.clear(); - cmSystemTools::ExpandListArgument(listString, list); + cmExpandList(listString, list); return true; case cmPolicies::NEW: 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; @@ -155,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; } @@ -168,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; } @@ -188,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; } @@ -213,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.c_str()); + 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); @@ -232,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 ";" @@ -243,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.c_str()); + 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); @@ -256,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 ";" @@ -268,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.c_str()); + 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; } @@ -296,41 +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().c_str()); + 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, ";").c_str()); + 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; } @@ -344,33 +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->c_str()); + 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, ";").c_str()); + 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; } @@ -378,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().c_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; } @@ -408,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; } @@ -425,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; } } @@ -434,17 +390,18 @@ bool cmListCommand::HandleInsertCommand(std::vector<std::string> const& args) args.end()); std::string value = cmJoin(varArgsExpanded, ";"); - this->Makefile->AddDefinition(listName, value.c_str()); + 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; } @@ -454,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.c_str()); + 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; } @@ -491,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.c_str()); + 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.c_str()); + 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; } @@ -537,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.c_str()); + 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 @@ -693,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; @@ -757,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; } @@ -853,7 +810,7 @@ bool cmListCommand::HandleTransformCommand( { "STRIP", 0, [&command](const std::string& s) -> std::string { if (command.Selector->InSelection(s)) { - return cmSystemTools::TrimWhitespace(s); + return cmTrimWhitespace(s); } return s; @@ -886,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; } @@ -896,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; } @@ -909,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) { @@ -927,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; } @@ -945,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; } @@ -975,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; @@ -990,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; @@ -1016,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 @@ -1038,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 = @@ -1051,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; } @@ -1064,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; } @@ -1083,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, ";").c_str()); + status.GetMakefile().AddDefinition(command.OutputName, + cmJoin(varArgsExpanded, ";")); return true; } @@ -1168,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; } @@ -1187,9 +1150,9 @@ bool cmListCommand::HandleSortCommand(std::vector<std::string> const& args) const std::string option = args[argumentIndex++]; if (option == "COMPARE") { if (sortCompare != cmStringSorter::Compare::UNINITIALIZED) { - std::string error = messageHint + "option \"" + option + - "\" has been specified multiple times."; - this->SetError(error); + std::string error = cmStrCat(messageHint, "option \"", option, + "\" has been specified multiple times."); + status.SetError(error); return false; } if (argumentIndex < args.size()) { @@ -1199,23 +1162,22 @@ bool cmListCommand::HandleSortCommand(std::vector<std::string> const& args) } else if (argument == "FILE_BASENAME") { sortCompare = cmStringSorter::Compare::FILE_BASENAME; } else { - std::string error = messageHint + "value \"" + argument + - "\" for option \"" + option + "\" is invalid."; - this->SetError(error); + std::string error = + cmStrCat(messageHint, "value \"", argument, "\" for option \"", + option, "\" is invalid."); + status.SetError(error); return false; } } else { - std::string error = - messageHint + "missing argument for option \"" + option + "\"."; - this->SetError(error); + status.SetError(cmStrCat(messageHint, "missing argument for option \"", + option, "\".")); return false; } } else if (option == "CASE") { if (sortCaseSensitivity != cmStringSorter::CaseSensitivity::UNINITIALIZED) { - std::string error = messageHint + "option \"" + option + - "\" has been specified multiple times."; - this->SetError(error); + status.SetError(cmStrCat(messageHint, "option \"", option, + "\" has been specified multiple times.")); return false; } if (argumentIndex < args.size()) { @@ -1225,23 +1187,21 @@ bool cmListCommand::HandleSortCommand(std::vector<std::string> const& args) } else if (argument == "INSENSITIVE") { sortCaseSensitivity = cmStringSorter::CaseSensitivity::INSENSITIVE; } else { - std::string error = messageHint + "value \"" + argument + - "\" for option \"" + option + "\" is invalid."; - this->SetError(error); + status.SetError(cmStrCat(messageHint, "value \"", argument, + "\" for option \"", option, + "\" is invalid.")); return false; } } else { - std::string error = - messageHint + "missing argument for option \"" + option + "\"."; - this->SetError(error); + status.SetError(cmStrCat(messageHint, "missing argument for option \"", + option, "\".")); return false; } } else if (option == "ORDER") { if (sortOrder != cmStringSorter::Order::UNINITIALIZED) { - std::string error = messageHint + "option \"" + option + - "\" has been specified multiple times."; - this->SetError(error); + status.SetError(cmStrCat(messageHint, "option \"", option, + "\" has been specified multiple times.")); return false; } if (argumentIndex < args.size()) { @@ -1251,21 +1211,19 @@ bool cmListCommand::HandleSortCommand(std::vector<std::string> const& args) } else if (argument == "DESCENDING") { sortOrder = cmStringSorter::Order::DESCENDING; } else { - std::string error = messageHint + "value \"" + argument + - "\" for option \"" + option + "\" is invalid."; - this->SetError(error); + status.SetError(cmStrCat(messageHint, "value \"", argument, + "\" for option \"", option, + "\" is invalid.")); return false; } } else { - std::string error = - messageHint + "missing argument for option \"" + option + "\"."; - this->SetError(error); + status.SetError(cmStrCat(messageHint, "missing argument for option \"", + option, "\".")); return false; } } else { - std::string error = - messageHint + "option \"" + option + "\" is unknown."; - this->SetError(error); + status.SetError( + cmStrCat(messageHint, "option \"", option, "\" is unknown.")); return false; } } @@ -1283,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; } @@ -1297,17 +1255,18 @@ bool cmListCommand::HandleSortCommand(std::vector<std::string> const& args) } std::string value = cmJoin(varArgsExpanded, ";"); - this->Makefile->AddDefinition(listName, value.c_str()); + 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; } @@ -1316,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; } @@ -1330,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; } @@ -1346,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, ";").c_str()); + 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) { @@ -1371,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; } @@ -1387,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)); @@ -1403,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.c_str()); + 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; } @@ -1431,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; } @@ -1475,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; } @@ -1497,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.c_str()); + 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 ea3d643..274d9fd 100644 --- a/Source/cmListCommand.h +++ b/Source/cmListCommand.h @@ -8,53 +8,13 @@ #include <string> #include <vector> -#include "cmCommand.h" - class cmExecutionStatus; -/** \class cmListCommand +/** * \brief Common list operations * */ -class cmListCommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - cmCommand* Clone() override { return new 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 df0d00c..ff3ecd9 100644 --- a/Source/cmListFileCache.cxx +++ b/Source/cmListFileCache.cxx @@ -7,6 +7,7 @@ #include "cmMessenger.h" #include "cmState.h" #include "cmStateDirectory.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include <assert.h> @@ -482,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; - cmSystemTools::ExpandListArgument(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/cmListFileCache.h b/Source/cmListFileCache.h index 9457415..5de1a74 100644 --- a/Source/cmListFileCache.h +++ b/Source/cmListFileCache.h @@ -6,7 +6,7 @@ #include "cmConfigure.h" // IWYU pragma: keep #include <iosfwd> -#include <memory> // IWYU pragma: keep +#include <memory> #include <stddef.h> #include <string> #include <utility> diff --git a/Source/cmLoadCacheCommand.cxx b/Source/cmLoadCacheCommand.cxx index b1fee8d..3fd7343 100644 --- a/Source/cmLoadCacheCommand.cxx +++ b/Source/cmLoadCacheCommand.cxx @@ -153,7 +153,7 @@ void cmLoadCacheCommand::CheckLine(const char* line) // prefix. var = this->Prefix + var; if (!value.empty()) { - this->Makefile->AddDefinition(var, value.c_str()); + this->Makefile->AddDefinition(var, value); } else { this->Makefile->RemoveDefinition(var); } diff --git a/Source/cmLoadCacheCommand.h b/Source/cmLoadCacheCommand.h index e0f6e4f..45e52f0 100644 --- a/Source/cmLoadCacheCommand.h +++ b/Source/cmLoadCacheCommand.h @@ -9,6 +9,8 @@ #include <string> #include <vector> +#include "cm_memory.hxx" + #include "cmCommand.h" class cmExecutionStatus; @@ -24,7 +26,10 @@ public: /** * This is a virtual constructor for the command. */ - cmCommand* Clone() override { return new cmLoadCacheCommand; } + std::unique_ptr<cmCommand> Clone() override + { + return cm::make_unique<cmLoadCacheCommand>(); + } /** * This is called when the command is first encountered in diff --git a/Source/cmLoadCommandCommand.cxx b/Source/cmLoadCommandCommand.cxx index 69751b6..180e65b 100644 --- a/Source/cmLoadCommandCommand.cxx +++ b/Source/cmLoadCommandCommand.cxx @@ -3,16 +3,21 @@ #include "cmLoadCommandCommand.h" #include <signal.h> + #include <sstream> #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <utility> + +#include "cm_memory.hxx" #include "cmCPluginAPI.cxx" #include "cmCPluginAPI.h" #include "cmDynamicLoader.h" #include "cmMakefile.h" #include "cmState.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" class cmExecutionStatus; @@ -21,30 +26,98 @@ class cmExecutionStatus; # include <malloc.h> /* for malloc/free on QNX */ #endif -extern "C" void TrapsForSignalsCFunction(int sig); +namespace { + +const char* LastName = nullptr; + +extern "C" void TrapsForSignals(int sig) +{ + fprintf(stderr, "CMake loaded command %s crashed with signal: %d.\n", + LastName, sig); +} + +struct SignalHandlerGuard +{ + explicit SignalHandlerGuard(const char* name) + { + LastName = name != nullptr ? name : "????"; + + signal(SIGSEGV, TrapsForSignals); +#ifdef SIGBUS + signal(SIGBUS, TrapsForSignals); +#endif + signal(SIGILL, TrapsForSignals); + } + + ~SignalHandlerGuard() + { + signal(SIGSEGV, nullptr); +#ifdef SIGBUS + signal(SIGBUS, nullptr); +#endif + signal(SIGILL, nullptr); + } + + SignalHandlerGuard(SignalHandlerGuard const&) = delete; + SignalHandlerGuard& operator=(SignalHandlerGuard const&) = delete; +}; + +struct LoadedCommandImpl : cmLoadedCommandInfo +{ + explicit LoadedCommandImpl(CM_INIT_FUNCTION init) + : cmLoadedCommandInfo{ 0, 0, &cmStaticCAPI, 0, + nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr } + { + init(this); + } + + ~LoadedCommandImpl() + { + if (this->Destructor) { + SignalHandlerGuard guard(this->Name); + this->Destructor(this); + } + if (this->Error != nullptr) { + free(this->Error); + } + } + + LoadedCommandImpl(LoadedCommandImpl const&) = delete; + LoadedCommandImpl& operator=(LoadedCommandImpl const&) = delete; + + int DoInitialPass(cmMakefile* mf, int argc, char* argv[]) + { + SignalHandlerGuard guard(this->Name); + return this->InitialPass(this, mf, argc, argv); + } + + void DoFinalPass(cmMakefile* mf) + { + SignalHandlerGuard guard(this->Name); + this->FinalPass(this, mf); + } +}; // a class for loadabple commands class cmLoadedCommand : public cmCommand { public: - cmLoadedCommand() + cmLoadedCommand() = default; + explicit cmLoadedCommand(CM_INIT_FUNCTION init) + : Impl(std::make_shared<LoadedCommandImpl>(init)) { - memset(&this->info, 0, sizeof(this->info)); - this->info.CAPI = &cmStaticCAPI; } - //! clean up any memory allocated by the plugin - ~cmLoadedCommand() override; - /** * This is a virtual constructor for the command. */ - cmCommand* Clone() override + std::unique_ptr<cmCommand> Clone() override { - cmLoadedCommand* newC = new cmLoadedCommand; + auto newC = cm::make_unique<cmLoadedCommand>(); // we must copy when we clone - memcpy(&newC->info, &this->info, sizeof(info)); - return newC; + newC->Impl = this->Impl; + return std::unique_ptr<cmCommand>(std::move(newC)); } /** @@ -54,66 +127,20 @@ public: bool InitialPass(std::vector<std::string> const& args, cmExecutionStatus&) override; - /** - * This is called at the end after all the information - * specified by the command is accumulated. Most commands do - * not implement this method. At this point, reading and - * writing to the cache can be done. - */ - void FinalPass() override; - bool HasFinalPass() const override - { - return this->info.FinalPass != nullptr; - } - - static const char* LastName; - static void TrapsForSignals(int sig) - { - fprintf(stderr, "CMake loaded command %s crashed with signal: %d.\n", - cmLoadedCommand::LastName, sig); - } - static void InstallSignalHandlers(const char* name, int remove = 0) - { - cmLoadedCommand::LastName = name; - if (!name) { - cmLoadedCommand::LastName = "????"; - } - - if (!remove) { - signal(SIGSEGV, TrapsForSignalsCFunction); -#ifdef SIGBUS - signal(SIGBUS, TrapsForSignalsCFunction); -#endif - signal(SIGILL, TrapsForSignalsCFunction); - } else { - signal(SIGSEGV, nullptr); -#ifdef SIGBUS - signal(SIGBUS, nullptr); -#endif - signal(SIGILL, nullptr); - } - } - - cmLoadedCommandInfo info; +private: + std::shared_ptr<LoadedCommandImpl> Impl; }; -extern "C" void TrapsForSignalsCFunction(int sig) -{ - cmLoadedCommand::TrapsForSignals(sig); -} - -const char* cmLoadedCommand::LastName = nullptr; - bool cmLoadedCommand::InitialPass(std::vector<std::string> const& args, cmExecutionStatus&) { - if (!info.InitialPass) { + if (!this->Impl->InitialPass) { return true; } // clear the error string - if (this->info.Error) { - free(this->info.Error); + if (this->Impl->Error) { + free(this->Impl->Error); } // create argc and argv and then invoke the command @@ -126,42 +153,26 @@ bool cmLoadedCommand::InitialPass(std::vector<std::string> const& args, for (i = 0; i < argc; ++i) { argv[i] = strdup(args[i].c_str()); } - cmLoadedCommand::InstallSignalHandlers(info.Name); - int result = info.InitialPass(&info, this->Makefile, argc, argv); - cmLoadedCommand::InstallSignalHandlers(info.Name, 1); + int result = this->Impl->DoInitialPass(this->Makefile, argc, argv); cmFreeArguments(argc, argv); if (result) { + if (this->Impl->FinalPass) { + auto impl = this->Impl; + this->Makefile->AddFinalAction( + [impl](cmMakefile& makefile) { impl->DoFinalPass(&makefile); }); + } return true; } /* Initial Pass must have failed so set the error string */ - if (this->info.Error) { - this->SetError(this->info.Error); + if (this->Impl->Error) { + this->SetError(this->Impl->Error); } return false; } -void cmLoadedCommand::FinalPass() -{ - if (this->info.FinalPass) { - cmLoadedCommand::InstallSignalHandlers(info.Name); - this->info.FinalPass(&this->info, this->Makefile); - cmLoadedCommand::InstallSignalHandlers(info.Name, 1); - } -} - -cmLoadedCommand::~cmLoadedCommand() -{ - if (this->info.Destructor) { - cmLoadedCommand::InstallSignalHandlers(info.Name); - this->info.Destructor(&this->info); - cmLoadedCommand::InstallSignalHandlers(info.Name, 1); - } - if (this->info.Error) { - free(this->info.Error); - } -} +} // namespace // cmLoadCommandCommand bool cmLoadCommandCommand::InitialPass(std::vector<std::string> const& args, @@ -173,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]; + std::string reportVar = cmStrCat("CMAKE_LOADED_COMMAND_", args[0]); this->Makefile->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( + this->Makefile->GetRequiredDefinition("CMAKE_SHARED_MODULE_PREFIX"), "cm", + args[0], + this->Makefile->GetRequiredDefinition("CMAKE_SHARED_MODULE_SUFFIX")); // search for the file std::vector<std::string> path; @@ -208,8 +217,8 @@ 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"; @@ -220,26 +229,23 @@ bool cmLoadCommandCommand::InitialPass(std::vector<std::string> const& args, } // Report what file was loaded for this command. - this->Makefile->AddDefinition(reportVar, fullPath.c_str()); + this->Makefile->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) { - // create a function blocker and set it up - cmLoadedCommand* f = new cmLoadedCommand(); - (*initFunction)(&f->info); - this->Makefile->GetState()->AddScriptedCommand(args[0], f); + this->Makefile->GetState()->AddScriptedCommand( + args[0], + cmLegacyCommandWrapper(cm::make_unique<cmLoadedCommand>(initFunction))); return true; } this->SetError("Attempt to load command failed. " diff --git a/Source/cmLoadCommandCommand.h b/Source/cmLoadCommandCommand.h index 021e6c7..d81cefb 100644 --- a/Source/cmLoadCommandCommand.h +++ b/Source/cmLoadCommandCommand.h @@ -8,6 +8,8 @@ #include <string> #include <vector> +#include "cm_memory.hxx" + #include "cmCommand.h" class cmExecutionStatus; @@ -15,7 +17,10 @@ class cmExecutionStatus; class cmLoadCommandCommand : public cmCommand { public: - cmCommand* Clone() override { return new cmLoadCommandCommand; } + std::unique_ptr<cmCommand> Clone() override + { + return cm::make_unique<cmLoadCommandCommand>(); + } bool InitialPass(std::vector<std::string> const& args, cmExecutionStatus& status) override; }; 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 3abf2dd..2e40543 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -21,27 +21,31 @@ #include "cmState.h" #include "cmStateDirectory.h" #include "cmStateTypes.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmTarget.h" #include "cmTestGenerator.h" #include "cmVersion.h" +#include "cm_string_view.hxx" #include "cmake.h" +#include "cmsys/RegularExpression.hxx" -#if defined(CMAKE_BUILD_WITH_CMAKE) +#if !defined(CMAKE_BOOTSTRAP) # define CM_LG_ENCODE_OBJECT_NAMES # include "cmCryptoHash.h" #endif -#include "cmsys/RegularExpression.hxx" #include <algorithm> #include <assert.h> #include <initializer_list> #include <iterator> +#include <memory> #include <sstream> #include <stdio.h> #include <string.h> #include <unordered_set> #include <utility> +#include <vector> #if defined(__HAIKU__) # include <FindDirectory.h> @@ -280,9 +284,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); @@ -307,8 +311,7 @@ void cmLocalGenerator::GenerateTestFiles() const char* testIncludeFiles = this->Makefile->GetProperty("TEST_INCLUDE_FILES"); if (testIncludeFiles) { - std::vector<std::string> includesList; - cmSystemTools::ExpandListArgument(testIncludeFiles, includesList); + std::vector<std::string> includesList = cmExpandedList(testIncludeFiles); for (std::string const& i : includesList) { fout << "include(\"" << i << "\")" << std::endl; } @@ -742,12 +745,10 @@ std::string cmLocalGenerator::GetIncludeFlags( OutputFormat shellFormat = forResponseFile ? RESPONSE : SHELL; std::ostringstream includeFlags; - std::string flagVar = "CMAKE_INCLUDE_FLAG_"; - flagVar += lang; - std::string const& includeFlag = this->Makefile->GetSafeDefinition(flagVar); - flagVar = "CMAKE_INCLUDE_FLAG_SEP_"; - flagVar += lang; - const char* sep = this->Makefile->GetDefinition(flagVar); + std::string const& includeFlag = + this->Makefile->GetSafeDefinition(cmStrCat("CMAKE_INCLUDE_FLAG_", lang)); + const char* sep = + this->Makefile->GetDefinition(cmStrCat("CMAKE_INCLUDE_FLAG_SEP_", lang)); bool quotePaths = false; if (this->Makefile->GetDefinition("CMAKE_QUOTE_INCLUDE_PATHS")) { quotePaths = true; @@ -764,23 +765,16 @@ std::string cmLocalGenerator::GetIncludeFlags( // Support special system include flag if it is available and the // normal flag is repeated for each directory. - std::string sysFlagVar = "CMAKE_INCLUDE_SYSTEM_FLAG_"; - sysFlagVar += lang; const char* sysIncludeFlag = nullptr; if (repeatFlag) { - sysIncludeFlag = this->Makefile->GetDefinition(sysFlagVar); + sysIncludeFlag = this->Makefile->GetDefinition( + cmStrCat("CMAKE_INCLUDE_SYSTEM_FLAG_", lang)); } - std::string fwSearchFlagVar = "CMAKE_"; - fwSearchFlagVar += lang; - fwSearchFlagVar += "_FRAMEWORK_SEARCH_FLAG"; - const char* fwSearchFlag = this->Makefile->GetDefinition(fwSearchFlagVar); - - std::string sysFwSearchFlagVar = "CMAKE_"; - sysFwSearchFlagVar += lang; - sysFwSearchFlagVar += "_SYSTEM_FRAMEWORK_SEARCH_FLAG"; - const char* sysFwSearchFlag = - this->Makefile->GetDefinition(sysFwSearchFlagVar); + const char* fwSearchFlag = this->Makefile->GetDefinition( + cmStrCat("CMAKE_", lang, "_FRAMEWORK_SEARCH_FLAG")); + const char* sysFwSearchFlag = this->Makefile->GetDefinition( + cmStrCat("CMAKE_", lang, "_SYSTEM_FRAMEWORK_SEARCH_FLAG")); bool flagUsed = false; std::set<std::string> emitted; @@ -790,9 +784,8 @@ std::string cmLocalGenerator::GetIncludeFlags( for (std::string const& i : includes) { if (fwSearchFlag && *fwSearchFlag && this->Makefile->IsOn("APPLE") && cmSystemTools::IsPathToFramework(i)) { - std::string frameworkDir = i; - frameworkDir += "/../"; - frameworkDir = cmSystemTools::CollapseFullPath(frameworkDir); + std::string const frameworkDir = + cmSystemTools::CollapseFullPath(cmStrCat(i, "/../")); if (emitted.insert(frameworkDir).second) { if (sysFwSearchFlag && target && target->IsSystemIncludeDirectory(i, config, lang)) { @@ -907,9 +900,8 @@ void cmLocalGenerator::AddCompileOptions(std::string& flags, std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(jmcExprGen); std::string isJMCEnabled = cge->Evaluate(this, config); - if (cmSystemTools::IsOn(isJMCEnabled)) { - std::vector<std::string> optVec; - cmSystemTools::ExpandListArgument(jmc, optVec); + if (cmIsOn(isJMCEnabled)) { + std::vector<std::string> optVec = cmExpandedList(jmc); this->AppendCompileOptions(flags, optVec); } } @@ -960,11 +952,9 @@ std::vector<BT<std::string>> cmLocalGenerator::GetIncludeDirectoriesImplicit( // These are intended to simulate additional implicit include directories. std::vector<std::string> userStandardDirs; { - std::string key = "CMAKE_"; - key += lang; - key += "_STANDARD_INCLUDE_DIRECTORIES"; - std::string const value = this->Makefile->GetSafeDefinition(key); - cmSystemTools::ExpandListArgument(value, userStandardDirs); + std::string const value = this->Makefile->GetSafeDefinition( + cmStrCat("CMAKE_", lang, "_STANDARD_INCLUDE_DIRECTORIES")); + cmExpandList(value, userStandardDirs); for (std::string& usd : userStandardDirs) { cmSystemTools::ConvertToUnixSlashes(usd); } @@ -986,12 +976,11 @@ std::vector<BT<std::string>> cmLocalGenerator::GetIncludeDirectoriesImplicit( // * Compilers like gfortran do not search their own implicit include // directories for modules ('.mod' files). if (lang != "Fortran") { - std::string key = "CMAKE_"; - key += lang; - key += "_IMPLICIT_INCLUDE_DIRECTORIES"; - if (const char* value = this->Makefile->GetDefinition(key)) { + const char* value = this->Makefile->GetDefinition( + cmStrCat("CMAKE_", lang, "_IMPLICIT_INCLUDE_DIRECTORIES")); + if (value != nullptr) { size_t const impDirVecOldSize = impDirVec.size(); - cmSystemTools::ExpandListArgument(value, impDirVec); + cmExpandList(value, impDirVec); // FIXME: Use cmRange with 'advance()' when it supports non-const. for (size_t i = impDirVecOldSize; i < impDirVec.size(); ++i) { cmSystemTools::ConvertToUnixSlashes(impDirVec[i]); @@ -1006,8 +995,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"); @@ -1017,7 +1005,7 @@ std::vector<BT<std::string>> cmLocalGenerator::GetIncludeDirectoriesImplicit( } for (std::string const& i : impDirVec) { - if (implicitSet.insert(i).second) { + if (implicitSet.insert(cmSystemTools::GetRealPath(i)).second) { implicitDirs.emplace_back(i); } } @@ -1028,14 +1016,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(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. @@ -1045,8 +1032,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. @@ -1082,7 +1069,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(udr.Value) != implicitSet.end()) { + if (cmContains(implicitSet, cmSystemTools::GetRealPath(udr.Value))) { emitBT(udr); } } @@ -1130,11 +1117,13 @@ void cmLocalGenerator::GetStaticLibraryFlags(std::string& flags, std::string const& linkLanguage, cmGeneratorTarget* target) { - this->AppendFlags( - flags, this->Makefile->GetSafeDefinition("CMAKE_STATIC_LINKER_FLAGS")); - if (!config.empty()) { - std::string name = "CMAKE_STATIC_LINKER_FLAGS_" + config; - this->AppendFlags(flags, this->Makefile->GetSafeDefinition(name)); + if (linkLanguage != "Swift") { + this->AppendFlags( + flags, this->Makefile->GetSafeDefinition("CMAKE_STATIC_LINKER_FLAGS")); + if (!config.empty()) { + std::string name = "CMAKE_STATIC_LINKER_FLAGS_" + config; + this->AppendFlags(flags, this->Makefile->GetSafeDefinition(name)); + } } this->AppendFlags(flags, target->GetProperty("STATIC_LIBRARY_FLAGS")); if (!config.empty()) { @@ -1170,12 +1159,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 += " "; } @@ -1203,9 +1190,8 @@ void cmLocalGenerator::GetTargetFlags( linkFlags += " "; } if (!buildType.empty()) { - std::string configLinkFlags = "LINK_FLAGS_"; - configLinkFlags += buildType; - targetLinkFlags = target->GetProperty(configLinkFlags); + targetLinkFlags = + target->GetProperty(cmStrCat("LINK_FLAGS_", buildType)); if (targetLinkFlags) { linkFlags += targetLinkFlags; linkFlags += " "; @@ -1227,9 +1213,8 @@ void cmLocalGenerator::GetTargetFlags( this->Makefile->GetSafeDefinition("CMAKE_EXE_LINKER_FLAGS"); linkFlags += " "; if (!buildType.empty()) { - std::string build = "CMAKE_EXE_LINKER_FLAGS_"; - build += buildType; - linkFlags += this->Makefile->GetSafeDefinition(build); + linkFlags += this->Makefile->GetSafeDefinition( + cmStrCat("CMAKE_EXE_LINKER_FLAGS_", buildType)); linkFlags += " "; } if (linkLanguage.empty()) { @@ -1250,11 +1235,8 @@ void cmLocalGenerator::GetTargetFlags( } if (target->IsExecutableWithExports()) { - std::string exportFlagVar = "CMAKE_EXE_EXPORTS_"; - exportFlagVar += linkLanguage; - exportFlagVar += "_FLAG"; - - linkFlags += this->Makefile->GetSafeDefinition(exportFlagVar); + linkFlags += this->Makefile->GetSafeDefinition( + cmStrCat("CMAKE_EXE_EXPORTS_", linkLanguage, "_FLAG")); linkFlags += " "; } } @@ -1265,8 +1247,7 @@ void cmLocalGenerator::GetTargetFlags( frameworkPath, linkPath); } - if (cmSystemTools::IsOn( - this->Makefile->GetDefinition("BUILD_SHARED_LIBS"))) { + if (cmIsOn(this->Makefile->GetDefinition("BUILD_SHARED_LIBS"))) { std::string sFlagVar = std::string("CMAKE_SHARED_BUILD_") + linkLanguage + std::string("_FLAGS"); linkFlags += this->Makefile->GetSafeDefinition(sFlagVar); @@ -1286,9 +1267,8 @@ void cmLocalGenerator::GetTargetFlags( linkFlags += " "; } if (!buildType.empty()) { - std::string configLinkFlags = "LINK_FLAGS_"; - configLinkFlags += buildType; - targetLinkFlags = target->GetProperty(configLinkFlags); + targetLinkFlags = + target->GetProperty(cmStrCat("LINK_FLAGS_", buildType)); if (targetLinkFlags) { linkFlags += targetLinkFlags; linkFlags += " "; @@ -1364,8 +1344,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); } @@ -1463,20 +1442,12 @@ void cmLocalGenerator::OutputLinkLibraries( } // Add standard libraries for this language. - std::string standardLibsVar = "CMAKE_"; - standardLibsVar += cli.GetLinkLanguage(); - standardLibsVar += "_STANDARD_LIBRARIES"; - std::string stdLibString; - if (const char* stdLibs = this->Makefile->GetDefinition(standardLibsVar)) { - stdLibString = stdLibs; - } + std::string stdLibString = this->Makefile->GetSafeDefinition( + cmStrCat("CMAKE_", cli.GetLinkLanguage(), "_STANDARD_LIBRARIES")); // Append the framework search path flags. - std::string fwSearchFlagVar = "CMAKE_"; - fwSearchFlagVar += linkLanguage; - fwSearchFlagVar += "_FRAMEWORK_SEARCH_FLAG"; - std::string fwSearchFlag = - this->Makefile->GetSafeDefinition(fwSearchFlagVar); + std::string fwSearchFlag = this->Makefile->GetSafeDefinition( + cmStrCat("CMAKE_", linkLanguage, "_FRAMEWORK_SEARCH_FLAG")); frameworkPath = linkLineComputer->ComputeFrameworkPath(cli, fwSearchFlag); linkPath = @@ -1511,8 +1482,10 @@ std::string cmLocalGenerator::GetLinkLibsCMP0065( } CM_FALLTHROUGH; case cmPolicies::OLD: - // OLD behavior is to always add the flags - add_shlib_flags = true; + // OLD behavior is to always add the flags, except on AIX where + // we compute symbol exports if ENABLE_EXPORTS is on. + add_shlib_flags = + !(tgt.Target->IsAIX() && tgt.GetPropertyAsBool("ENABLE_EXPORTS")); break; case cmPolicies::REQUIRED_IF_USED: case cmPolicies::REQUIRED_ALWAYS: @@ -1521,16 +1494,16 @@ std::string cmLocalGenerator::GetLinkLibsCMP0065( cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0065)); CM_FALLTHROUGH; case cmPolicies::NEW: - // NEW behavior is to only add the flags if ENABLE_EXPORTS is on - add_shlib_flags = tgt.GetPropertyAsBool("ENABLE_EXPORTS"); + // NEW behavior is to only add the flags if ENABLE_EXPORTS is on, + // except on AIX where we compute symbol exports. + add_shlib_flags = + !tgt.Target->IsAIX() && tgt.GetPropertyAsBool("ENABLE_EXPORTS"); break; } if (add_shlib_flags) { - std::string linkFlagsVar = "CMAKE_SHARED_LIBRARY_LINK_"; - linkFlagsVar += linkLanguage; - linkFlagsVar += "_FLAGS"; - linkFlags = this->Makefile->GetSafeDefinition(linkFlagsVar); + linkFlags = this->Makefile->GetSafeDefinition( + cmStrCat("CMAKE_SHARED_LIBRARY_LINK_", linkLanguage, "_FLAGS")); } } return linkFlags; @@ -1588,10 +1561,19 @@ void cmLocalGenerator::AddLanguageFlags(std::string& flags, const std::string& config) { // Add language-specific flags. - std::string flagsVar = "CMAKE_"; - flagsVar += lang; - flagsVar += "_FLAGS"; - this->AddConfigVariableFlags(flags, flagsVar, config); + 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. @@ -1749,9 +1731,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; } @@ -1762,10 +1743,9 @@ void cmLocalGenerator::AddSharedFlags(std::string& flags, // Add flags for dealing with shared libraries for this language. if (shared) { - flagsVar = "CMAKE_SHARED_LIBRARY_"; - flagsVar += lang; - flagsVar += "_FLAGS"; - this->AppendFlags(flags, this->Makefile->GetDefinition(flagsVar)); + this->AppendFlags(flags, + this->Makefile->GetDefinition( + cmStrCat("CMAKE_SHARED_LIBRARY_", lang, "_FLAGS"))); } } @@ -1784,7 +1764,7 @@ void cmLocalGenerator::AddCompilerRequirementFlag( std::string extProp = lang + "_EXTENSIONS"; bool ext = true; if (const char* extPropValue = target->GetProperty(extProp)) { - if (cmSystemTools::IsOff(extPropValue)) { + if (cmIsOff(extPropValue)) { ext = false; } } @@ -1798,8 +1778,7 @@ void cmLocalGenerator::AddCompilerRequirementFlag( "CMAKE_" + lang + "_EXTENSION_COMPILE_OPTION"; if (const char* opt = target->Target->GetMakefile()->GetDefinition(option_flag)) { - std::vector<std::string> optVec; - cmSystemTools::ExpandListArgument(opt, optVec); + std::vector<std::string> optVec = cmExpandedList(opt); for (std::string const& i : optVec) { this->AppendFlagEscape(flags, i); } @@ -1827,8 +1806,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; - cmSystemTools::ExpandListArgument(opt, optVec); + std::vector<std::string> optVec = cmExpandedList(opt); for (std::string const& i : optVec) { this->AppendFlagEscape(flags, i); } @@ -1888,8 +1866,7 @@ void cmLocalGenerator::AddCompilerRequirementFlag( std::string const& opt = target->Target->GetMakefile()->GetRequiredDefinition(option_flag); - std::vector<std::string> optVec; - cmSystemTools::ExpandListArgument(opt, optVec); + std::vector<std::string> optVec = cmExpandedList(opt); for (std::string const& i : optVec) { this->AppendFlagEscape(flags, i); } @@ -1901,12 +1878,11 @@ void cmLocalGenerator::AddCompilerRequirementFlag( // for which a flag is defined. for (; stdIt < defaultStdIt; ++stdIt) { std::string option_flag = - "CMAKE_" + lang + *stdIt + "_" + type + "_COMPILE_OPTION"; + cmStrCat("CMAKE_", lang, *stdIt, "_", type, "_COMPILE_OPTION"); if (const char* opt = target->Target->GetMakefile()->GetDefinition(option_flag)) { - std::vector<std::string> optVec; - cmSystemTools::ExpandListArgument(opt, optVec); + std::vector<std::string> optVec = cmExpandedList(opt); for (std::string const& i : optVec) { this->AppendFlagEscape(flags, i); } @@ -2054,9 +2030,7 @@ bool cmLocalGenerator::GetShouldUseOldFlags(bool shared, std::string originalFlags = this->GlobalGenerator->GetSharedLibFlagsForLanguage(lang); if (shared) { - std::string flagsVar = "CMAKE_SHARED_LIBRARY_"; - flagsVar += lang; - flagsVar += "_FLAGS"; + std::string flagsVar = cmStrCat("CMAKE_SHARED_LIBRARY_", lang, "_FLAGS"); std::string const& flags = this->Makefile->GetSafeDefinition(flagsVar); if (flags != originalFlags) { @@ -2095,20 +2069,15 @@ void cmLocalGenerator::AddPositionIndependentFlags(std::string& flags, std::string picFlags; if (targetType == cmStateEnums::EXECUTABLE) { - std::string flagsVar = "CMAKE_"; - flagsVar += lang; - flagsVar += "_COMPILE_OPTIONS_PIE"; - picFlags = this->Makefile->GetSafeDefinition(flagsVar); + picFlags = this->Makefile->GetSafeDefinition( + cmStrCat("CMAKE_", lang, "_COMPILE_OPTIONS_PIE")); } if (picFlags.empty()) { - std::string flagsVar = "CMAKE_"; - flagsVar += lang; - flagsVar += "_COMPILE_OPTIONS_PIC"; - picFlags = this->Makefile->GetSafeDefinition(flagsVar); + picFlags = this->Makefile->GetSafeDefinition( + cmStrCat("CMAKE_", lang, "_COMPILE_OPTIONS_PIC")); } if (!picFlags.empty()) { - std::vector<std::string> options; - cmSystemTools::ExpandListArgument(picFlags, options); + std::vector<std::string> options = cmExpandedList(picFlags); for (std::string const& o : options) { this->AppendFlagEscape(flags, o); } @@ -2179,8 +2148,7 @@ void cmLocalGenerator::AppendIPOLinkerFlags(std::string& flags, return; } - std::vector<std::string> flagsList; - cmSystemTools::ExpandListArgument(rawFlagsList, flagsList); + std::vector<std::string> flagsList = cmExpandedList(rawFlagsList); for (std::string const& o : flagsList) { this->AppendFlagEscape(flags, o); } @@ -2201,10 +2169,10 @@ void cmLocalGenerator::AppendPositionIndependentLinkerFlags( return; } - const std::string mode = cmSystemTools::IsOn(PICValue) ? "PIE" : "NO_PIE"; + const std::string mode = cmIsOn(PICValue) ? "PIE" : "NO_PIE"; std::string supported = "CMAKE_" + lang + "_LINK_" + mode + "_SUPPORTED"; - if (cmSystemTools::IsOff(this->Makefile->GetDefinition(supported))) { + if (cmIsOff(this->Makefile->GetDefinition(supported))) { return; } @@ -2215,8 +2183,7 @@ void cmLocalGenerator::AppendPositionIndependentLinkerFlags( return; } - std::vector<std::string> flagsList; - cmSystemTools::ExpandListArgument(pieFlags, flagsList); + std::vector<std::string> flagsList = cmExpandedList(pieFlags); for (const auto& flag : flagsList) { this->AppendFlagEscape(flags, flag); } @@ -2232,8 +2199,7 @@ void cmLocalGenerator::AppendCompileOptions(std::string& options, } // Expand the list of options. - std::vector<std::string> options_vec; - cmSystemTools::ExpandListArgument(options_list, options_vec); + std::vector<std::string> options_vec = cmExpandedList(options_list); this->AppendCompileOptions(options, options_vec, regex); } @@ -2267,8 +2233,7 @@ void cmLocalGenerator::AppendIncludeDirectories( } // Expand the list of includes. - std::vector<std::string> includes_vec; - cmSystemTools::ExpandListArgument(includes_list, includes_vec); + std::vector<std::string> includes_vec = cmExpandedList(includes_list); this->AppendIncludeDirectories(includes, includes_vec, sourceFile); } @@ -2293,7 +2258,7 @@ void cmLocalGenerator::AppendIncludeDirectories( std::string inc = include; - if (!cmSystemTools::IsOff(inc)) { + if (!cmIsOff(inc)) { cmSystemTools::ConvertToUnixSlashes(inc); } @@ -2345,10 +2310,8 @@ void cmLocalGenerator::JoinDefines(const std::set<std::string>& defines, // Lookup the define flag for the current language. std::string dflag = "-D"; if (!lang.empty()) { - std::string defineFlagVar = "CMAKE_"; - defineFlagVar += lang; - defineFlagVar += "_DEFINE_FLAG"; - const char* df = this->Makefile->GetDefinition(defineFlagVar); + const char* df = + this->Makefile->GetDefinition(cmStrCat("CMAKE_", lang, "_DEFINE_FLAG")); if (df && *df) { dflag = df; } @@ -2394,13 +2357,10 @@ void cmLocalGenerator::AppendFeatureOptions(std::string& flags, const std::string& lang, const char* feature) { - std::string optVar = "CMAKE_"; - optVar += lang; - optVar += "_COMPILE_OPTIONS_"; - optVar += feature; - if (const char* optionList = this->Makefile->GetDefinition(optVar)) { - std::vector<std::string> options; - cmSystemTools::ExpandListArgument(optionList, options); + const char* optionList = this->Makefile->GetDefinition( + cmStrCat("CMAKE_", lang, "_COMPILE_OPTIONS_", feature)); + if (optionList != nullptr) { + std::vector<std::string> options = cmExpandedList(optionList); for (std::string const& o : options) { this->AppendFlagEscape(flags, o); } @@ -2555,8 +2515,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. @@ -2751,10 +2711,8 @@ std::string cmLocalGenerator::GetObjectFileNameWithoutTarget( if (!replaceExt) { std::string lang = source.GetLanguage(); if (!lang.empty()) { - std::string repVar = "CMAKE_"; - repVar += lang; - repVar += "_OUTPUT_EXTENSION_REPLACE"; - replaceExt = this->Makefile->IsOn(repVar); + replaceExt = this->Makefile->IsOn( + cmStrCat("CMAKE_", lang, "_OUTPUT_EXTENSION_REPLACE")); } } @@ -2963,7 +2921,7 @@ void cmLocalGenerator::GenerateAppleInfoPList(cmGeneratorTarget* target, // back to the directory-level values set by the user. cmMakefile* mf = this->Makefile; cmMakefile::ScopePushPop varScope(mf); - mf->AddDefinition("MACOSX_BUNDLE_EXECUTABLE_NAME", targetName.c_str()); + mf->AddDefinition("MACOSX_BUNDLE_EXECUTABLE_NAME", targetName); cmLGInfoProp(mf, target, "MACOSX_BUNDLE_INFO_STRING"); cmLGInfoProp(mf, target, "MACOSX_BUNDLE_ICON_FILE"); cmLGInfoProp(mf, target, "MACOSX_BUNDLE_GUI_IDENTIFIER"); @@ -3002,7 +2960,7 @@ void cmLocalGenerator::GenerateFrameworkInfoPList( // back to the directory-level values set by the user. cmMakefile* mf = this->Makefile; cmMakefile::ScopePushPop varScope(mf); - mf->AddDefinition("MACOSX_FRAMEWORK_NAME", targetName.c_str()); + mf->AddDefinition("MACOSX_FRAMEWORK_NAME", targetName); cmLGInfoProp(mf, target, "MACOSX_FRAMEWORK_ICON_FILE"); cmLGInfoProp(mf, target, "MACOSX_FRAMEWORK_IDENTIFIER"); cmLGInfoProp(mf, target, "MACOSX_FRAMEWORK_SHORT_VERSION_STRING"); diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h index f0c6806..455e491 100644 --- a/Source/cmLocalGenerator.h +++ b/Source/cmLocalGenerator.h @@ -461,7 +461,7 @@ private: void ComputeObjectMaxPath(); }; -#if defined(CMAKE_BUILD_WITH_CMAKE) +#if !defined(CMAKE_BOOTSTRAP) bool cmLocalGeneratorCheckObjectName(std::string& objName, std::string::size_type dir_len, std::string::size_type max_total_len); 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 81cafa3..e28b876 100644 --- a/Source/cmLocalNinjaGenerator.cxx +++ b/Source/cmLocalNinjaGenerator.cxx @@ -5,7 +5,7 @@ #include <algorithm> #include <assert.h> #include <iterator> -#include <memory> // IWYU pragma: keep +#include <memory> #include <sstream> #include <stdio.h> #include <utility> @@ -25,6 +25,7 @@ #include "cmSourceFile.h" #include "cmState.h" #include "cmStateTypes.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmake.h" #include "cmsys/FStream.hxx" @@ -102,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 @@ -221,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; - cmSystemTools::ExpandListArgument(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; @@ -300,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 += '/'; @@ -555,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(), @@ -613,7 +612,7 @@ void cmLocalNinjaGenerator::AdditionalCleanFiles() { cmGeneratorExpression ge; auto cge = ge.Parse(prop_value); - cmSystemTools::ExpandListArgument( + cmExpandList( cge->Evaluate(this, this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE")), cleanFiles); diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx index c392e97..106e506 100644 --- a/Source/cmLocalUnixMakefileGenerator3.cxx +++ b/Source/cmLocalUnixMakefileGenerator3.cxx @@ -5,11 +5,12 @@ #include "cmsys/FStream.hxx" #include "cmsys/Terminal.h" #include <algorithm> -#include <memory> // IWYU pragma: keep #include <sstream> #include <stdio.h> #include <utility> +#include "cm_memory.hxx" + #include "cmAlgorithms.h" #include "cmCustomCommand.h" // IWYU pragma: keep #include "cmCustomCommandGenerator.h" @@ -31,6 +32,7 @@ #include "cmStateDirectory.h" #include "cmStateSnapshot.h" #include "cmStateTypes.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmVersion.h" #include "cmake.h" @@ -38,7 +40,7 @@ // Include dependency scanners for supported languages. Only the // C/C++ scanner is needed for bootstrapping CMake. #include "cmDependsC.h" -#ifdef CMAKE_BUILD_WITH_CMAKE +#ifndef CMAKE_BOOTSTRAP # include "cmDependsFortran.h" # include "cmDependsJava.h" #endif @@ -162,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; @@ -363,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()); @@ -386,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( @@ -405,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( @@ -425,9 +420,9 @@ void cmLocalUnixMakefileGenerator3::WriteLocalMakefileTargets( void cmLocalUnixMakefileGenerator3::WriteDirectoryInformationFile() { - std::string infoFileName = this->GetCurrentBinaryDirectory(); - infoFileName += "/CMakeFiles"; - infoFileName += "/CMakeDirectoryInformation.cmake"; + std::string infoFileName = + cmStrCat(this->GetCurrentBinaryDirectory(), + "/CMakeFiles/CMakeDirectoryInformation.cmake"); // Open the output file. cmGeneratedFileStream infoFileStream(infoFileName); @@ -483,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; } @@ -766,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)); @@ -819,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; } @@ -851,7 +844,7 @@ void cmLocalUnixMakefileGenerator3::AppendRuleDepend( // it is specifically enabled by the user or project. const char* nodep = this->Makefile->GetDefinition("CMAKE_SKIP_RULE_DEPENDENCY"); - if (!nodep || cmSystemTools::IsOff(nodep)) { + if (!nodep || cmIsOff(nodep)) { depends.emplace_back(ruleFileName); } } @@ -961,7 +954,7 @@ void cmLocalUnixMakefileGenerator3::AppendCustomCommand( // This command was specified as a path to a file in the // current directory. Add a leading "./" so it can run // without the current directory being in the search path. - cmd = "./" + cmd; + cmd = cmStrCat("./", cmd); } std::string launcher; @@ -1015,18 +1008,16 @@ void cmLocalUnixMakefileGenerator3::AppendCustomCommand( std::string::size_type rcurly = cmd.find('}'); if (rcurly == std::string::npos || rcurly > lcurly) { // The first curly is a left curly. Use the hack. - std::string hack_cmd = cmd.substr(0, lcurly); - hack_cmd += "{{}"; - hack_cmd += cmd.substr(lcurly + 1); - cmd = hack_cmd; + cmd = + cmStrCat(cmd.substr(0, lcurly), "{{}", cmd.substr(lcurly + 1)); } } } if (launcher.empty()) { if (useCall) { - cmd = "call " + cmd; + cmd = cmStrCat("call ", cmd); } else if (this->IsNMake() && cmd[0] == '"') { - cmd = "echo >nul && " + cmd; + cmd = cmStrCat("echo >nul && ", cmd); } } commands1.push_back(std::move(cmd)); @@ -1045,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; @@ -1068,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)); } @@ -1102,7 +1092,7 @@ void cmLocalUnixMakefileGenerator3::AppendDirectoryCleanCommand( this->Makefile->GetProperty("ADDITIONAL_CLEAN_FILES")) { cmGeneratorExpression ge; std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(prop_value); - cmSystemTools::ExpandListArgument( + cmExpandList( cge->Evaluate(this, this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE")), cleanFiles); @@ -1115,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); @@ -1135,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)); } } @@ -1184,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( @@ -1225,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. @@ -1344,9 +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"; - dirInfoFile += "/CMakeDirectoryInformation.cmake"; + std::string dirInfoFile = + cmStrCat(this->GetCurrentBinaryDirectory(), + "/CMakeFiles/CMakeDirectoryInformation.cmake"); int result; if (!ftc->Compare(internalDependFile, dirInfoFile, &result) || result < 0) { @@ -1388,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); @@ -1410,9 +1400,9 @@ bool cmLocalUnixMakefileGenerator3::ScanDependencies( cmMakefile* mf = this->Makefile; bool haveDirectoryInfo = false; { - std::string dirInfoFile = this->GetCurrentBinaryDirectory(); - dirInfoFile += "/CMakeFiles"; - dirInfoFile += "/CMakeDirectoryInformation.cmake"; + std::string dirInfoFile = + cmStrCat(this->GetCurrentBinaryDirectory(), + "/CMakeFiles/CMakeDirectoryInformation.cmake"); if (mf->ReadListFile(dirInfoFile) && !cmSystemTools::GetErrorOccuredFlag()) { haveDirectoryInfo = true; @@ -1423,7 +1413,7 @@ bool cmLocalUnixMakefileGenerator3::ScanDependencies( if (haveDirectoryInfo) { // Test whether we need to force Unix paths. if (const char* force = mf->GetDefinition("CMAKE_FORCE_UNIX_PATHS")) { - if (!cmSystemTools::IsOff(force)) { + if (!cmIsOff(force)) { cmSystemTools::SetForceUnixPaths(true); } } @@ -1465,9 +1455,8 @@ bool cmLocalUnixMakefileGenerator3::ScanDependencies( this->WriteDisclaimer(internalRuleFileStream); // for each language we need to scan, scan it - std::vector<std::string> langs; - cmSystemTools::ExpandListArgument( - 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 @@ -1477,7 +1466,7 @@ bool cmLocalUnixMakefileGenerator3::ScanDependencies( // TODO: Handle RC (resource files) dependencies correctly. scanner = cm::make_unique<cmDependsC>(this, targetDir, lang, &validDeps); } -#ifdef CMAKE_BUILD_WITH_CMAKE +#ifndef CMAKE_BOOTSTRAP else if (lang == "Fortran") { ruleFileStream << "# Note that incremental build could trigger " << "a call to cmake_copy_f90_mod on each re-build\n"; @@ -1511,8 +1500,7 @@ void cmLocalUnixMakefileGenerator3::CheckMultipleOutputs(bool verbose) } // Convert the string to a list and preserve empty entries. - std::vector<std::string> pairs; - cmSystemTools::ExpandListArgument(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++; @@ -1625,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"); @@ -1634,16 +1622,15 @@ 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 "; progCmd << this->ConvertToOutputFormat( cmSystemTools::CollapseFullPath(progressDir), cmOutputConverter::SHELL); - std::string progressFile = "/CMakeFiles"; - progressFile += "/progress.marks"; + std::string progressFile = "/CMakeFiles/progress.marks"; std::string progressFileNameFull = this->ConvertToFullPath(progressFile); progCmd << " " << this->ConvertToOutputFormat( @@ -1651,8 +1638,7 @@ void cmLocalUnixMakefileGenerator3::WriteLocalAllRules( cmOutputConverter::SHELL); commands.push_back(progCmd.str()); } - std::string mf2Dir = "CMakeFiles/"; - mf2Dir += "Makefile2"; + std::string mf2Dir = "CMakeFiles/Makefile2"; commands.push_back(this->GetRecursiveMakeCall(mf2Dir, recursiveTarget)); this->CreateCDCommand(commands, this->GetBinaryDirectory(), this->GetCurrentBinaryDirectory()); @@ -1668,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)); @@ -1684,13 +1669,12 @@ 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 = this->Makefile->GetDefinition("CMAKE_SKIP_INSTALL_ALL_DEPENDENCY"); - if (!noall || cmSystemTools::IsOff(noall)) { + if (!noall || cmIsOff(noall)) { // Drive the build before installing. depends.emplace_back("all"); } else if (regenerate) { @@ -1712,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(), @@ -1743,8 +1726,7 @@ void cmLocalUnixMakefileGenerator3::ClearDependencies(cmMakefile* mf, if (!infoDef) { return; } - std::vector<std::string> files; - cmSystemTools::ExpandListArgument(infoDef, files); + std::vector<std::string> files = cmExpandedList(infoDef); // Each depend information file corresponds to a target. Clear the // dependencies for that target. @@ -1846,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 @@ -1912,11 +1893,11 @@ void cmLocalUnixMakefileGenerator3::WriteDependLanguageInfo( std::vector<std::string> transformRules; if (const char* xform = this->Makefile->GetProperty("IMPLICIT_DEPENDS_INCLUDE_TRANSFORM")) { - cmSystemTools::ExpandListArgument(xform, transformRules); + cmExpandList(xform, transformRules); } if (const char* xform = target->GetProperty("IMPLICIT_DEPENDS_INCLUDE_TRANSFORM")) { - cmSystemTools::ExpandListArgument(xform, transformRules); + cmExpandList(xform, transformRules); } if (!transformRules.empty()) { cmakefileStream << "set(CMAKE_INCLUDE_TRANSFORMS\n"; @@ -1939,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); @@ -2073,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 @@ -2117,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 8154f3e..2c91974 100644 --- a/Source/cmLocalVisualStudio7Generator.cxx +++ b/Source/cmLocalVisualStudio7Generator.cxx @@ -97,11 +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 += "/"; - 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)) { @@ -144,11 +141,10 @@ 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 += "/"; - stampName += "generate.stamp"; + stampName += "/generate.stamp"; cmsys::ofstream stamp(stampName.c_str()); stamp << "# CMake generation timestamp file for this directory.\n"; @@ -158,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"; @@ -199,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 { @@ -228,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()) { @@ -253,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); @@ -721,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. @@ -733,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 = @@ -956,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 += " "; @@ -989,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" @@ -1005,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"; @@ -1049,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"; @@ -1071,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); @@ -1081,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()) { @@ -1096,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) { @@ -1130,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"; @@ -1152,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); @@ -1190,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; @@ -1509,8 +1477,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); @@ -1525,8 +1492,7 @@ cmLocalVisualStudio7GeneratorFCInfo::cmLocalVisualStudio7GeneratorFCInfo( // Check for extra object-file dependencies. if (const char* deps = sf.GetProperty("OBJECT_DEPENDS")) { - std::vector<std::string> depends; - cmSystemTools::ExpandListArgument(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) { @@ -1540,9 +1506,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; } @@ -1586,13 +1551,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; } @@ -2142,8 +2103,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", @@ -2153,9 +2113,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/cmLocalVisualStudioGenerator.h b/Source/cmLocalVisualStudioGenerator.h index 3fdafd2..585eb3c 100644 --- a/Source/cmLocalVisualStudioGenerator.h +++ b/Source/cmLocalVisualStudioGenerator.h @@ -6,7 +6,7 @@ #include "cmConfigure.h" // IWYU pragma: keep #include <map> -#include <memory> // IWYU pragma: keep +#include <memory> #include <string> #include "cmGlobalVisualStudioGenerator.h" 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/cmMachO.cxx b/Source/cmMachO.cxx index d4af1e0..bec3ad8 100644 --- a/Source/cmMachO.cxx +++ b/Source/cmMachO.cxx @@ -2,12 +2,15 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmMachO.h" +#include "cmAlgorithms.h" #include "cmsys/FStream.hxx" -#include <algorithm> -#include <stddef.h> + +#include <cstddef> #include <string> #include <vector> +#include "cm_memory.hxx" + // Include the Mach-O format information system header. #include <mach-o/fat.h> #include <mach-o/loader.h> @@ -120,7 +123,7 @@ protected: // Implementation for reading Mach-O header and load commands. // This is 32 or 64 bit arch specific. -template <class T> +template <typename T> class cmMachOHeaderAndLoadCommandsImpl : public cmMachOHeaderAndLoadCommands { public: @@ -306,15 +309,11 @@ bool cmMachOInternal::read_mach_o(uint32_t file_offset) // External class implementation. cmMachO::cmMachO(const char* fname) - : Internal(nullptr) + : Internal(cm::make_unique<cmMachOInternal>(fname)) { - this->Internal = new cmMachOInternal(fname); } -cmMachO::~cmMachO() -{ - delete this->Internal; -} +cmMachO::~cmMachO() = default; std::string const& cmMachO::GetErrorMessage() const { diff --git a/Source/cmMachO.h b/Source/cmMachO.h index 5482465..0c44b55 100644 --- a/Source/cmMachO.h +++ b/Source/cmMachO.h @@ -41,7 +41,7 @@ public: private: friend class cmMachOInternal; bool Valid() const; - cmMachOInternal* Internal; + std::unique_ptr<cmMachOInternal> Internal; }; #endif diff --git a/Source/cmMacroCommand.cxx b/Source/cmMacroCommand.cxx index e9c6aea..201cc13 100644 --- a/Source/cmMacroCommand.cxx +++ b/Source/cmMacroCommand.cxx @@ -2,48 +2,36 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmMacroCommand.h" -#include <sstream> #include <stdio.h> #include <utility> +#include "cm_memory.hxx" +#include "cm_static_string_view.hxx" +#include "cm_string_view.hxx" + #include "cmAlgorithms.h" #include "cmExecutionStatus.h" +#include "cmFunctionBlocker.h" +#include "cmListFileCache.h" #include "cmMakefile.h" #include "cmPolicies.h" #include "cmRange.h" #include "cmState.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" +namespace { + // define the class for macro commands -class cmMacroHelperCommand : public cmCommand +class cmMacroHelperCommand { public: /** - * This is a virtual constructor for the command. - */ - cmCommand* Clone() override - { - cmMacroHelperCommand* newC = new cmMacroHelperCommand; - // we must copy when we clone - newC->Args = this->Args; - newC->Functions = this->Functions; - newC->FilePath = this->FilePath; - newC->Policies = this->Policies; - return newC; - } - - /** * This is called when the command is first encountered in * the CMakeLists.txt file. */ - bool InvokeInitialPass(const std::vector<cmListFileArgument>& args, - cmExecutionStatus&) override; - - bool InitialPass(std::vector<std::string> const&, - cmExecutionStatus&) override - { - return false; - } + bool operator()(std::vector<cmListFileArgument> const& args, + cmExecutionStatus& inStatus) const; std::vector<std::string> Args; std::vector<cmListFileFunction> Functions; @@ -51,30 +39,31 @@ public: std::string FilePath; }; -bool cmMacroHelperCommand::InvokeInitialPass( - const std::vector<cmListFileArgument>& args, cmExecutionStatus& inStatus) +bool cmMacroHelperCommand::operator()( + std::vector<cmListFileArgument> const& args, + cmExecutionStatus& inStatus) const { + cmMakefile& makefile = inStatus.GetMakefile(); + // Expand the argument list to the macro. std::vector<std::string> expandedArgs; - this->Makefile->ExpandArguments(args, expandedArgs); + makefile.ExpandArguments(args, expandedArgs); // 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 = - "Macro invoked with incorrect arguments for macro named: "; - errorMsg += this->Args[0]; - this->SetError(errorMsg); + cmStrCat("Macro invoked with incorrect arguments for macro named: ", + this->Args[0]); + inStatus.SetError(errorMsg); return false; } - cmMakefile::MacroPushPop macroScope(this->Makefile, this->FilePath, + cmMakefile::MacroPushPop macroScope(&makefile, this->FilePath, 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); @@ -130,9 +119,8 @@ bool cmMacroHelperCommand::InvokeInitialPass( arg.Line = k.Line; newLFF.Arguments.push_back(std::move(arg)); } - cmExecutionStatus status; - if (!this->Makefile->ExecuteCommand(newLFF, status) || - status.GetNestedError()) { + cmExecutionStatus status(makefile); + if (!makefile.ExecuteCommand(newLFF, status) || status.GetNestedError()) { // The error message should have already included the call stack // so we do not need to report an error here. macroScope.Quiet(); @@ -151,68 +139,59 @@ bool cmMacroHelperCommand::InvokeInitialPass( return true; } -bool cmMacroFunctionBlocker::IsFunctionBlocked(const cmListFileFunction& lff, - cmMakefile& mf, - cmExecutionStatus&) +class cmMacroFunctionBlocker : public cmFunctionBlocker { - // record commands until we hit the ENDMACRO - // at the ENDMACRO call we shift gears and start looking for invocations - if (lff.Name.Lower == "macro") { - this->Depth++; - } else if (lff.Name.Lower == "endmacro") { - // if this is the endmacro for this macro then execute - if (!this->Depth) { - mf.AppendProperty("MACROS", this->Args[0].c_str()); - // create a new command and add it to cmake - cmMacroHelperCommand* f = new cmMacroHelperCommand(); - f->Args = this->Args; - f->Functions = this->Functions; - f->FilePath = this->GetStartingContext().FilePath; - mf.RecordPolicies(f->Policies); - mf.GetState()->AddScriptedCommand(this->Args[0], f); - // remove the function blocker now that the macro is defined - mf.RemoveFunctionBlocker(this, lff); - return true; - } - // decrement for each nested macro that ends - this->Depth--; - } +public: + cm::string_view StartCommandName() const override { return "macro"_s; } + cm::string_view EndCommandName() const override { return "endmacro"_s; } - // if it wasn't an endmacro and we are not executing then we must be - // recording - this->Functions.push_back(lff); - return true; -} + bool ArgumentsMatch(cmListFileFunction const&, + cmMakefile& mf) const override; + + bool Replay(std::vector<cmListFileFunction> functions, + cmExecutionStatus& status) override; + + std::vector<std::string> Args; +}; -bool cmMacroFunctionBlocker::ShouldRemove(const cmListFileFunction& lff, - cmMakefile& mf) +bool cmMacroFunctionBlocker::ArgumentsMatch(cmListFileFunction const& lff, + cmMakefile& mf) const { - if (lff.Name.Lower == "endmacro") { - std::vector<std::string> expandedArguments; - mf.ExpandArguments(lff.Arguments, expandedArguments, - this->GetStartingContext().FilePath.c_str()); - // if the endmacro has arguments make sure they - // match the arguments of the macro - if ((expandedArguments.empty() || - (expandedArguments[0] == this->Args[0]))) { - return true; - } - } + std::vector<std::string> expandedArguments; + mf.ExpandArguments(lff.Arguments, expandedArguments, + this->GetStartingContext().FilePath.c_str()); + return expandedArguments.empty() || expandedArguments[0] == this->Args[0]; +} - return false; +bool cmMacroFunctionBlocker::Replay(std::vector<cmListFileFunction> functions, + cmExecutionStatus& status) +{ + cmMakefile& mf = status.GetMakefile(); + mf.AppendProperty("MACROS", this->Args[0].c_str()); + // create a new command and add it to cmake + cmMacroHelperCommand f; + f.Args = this->Args; + f.Functions = std::move(functions); + f.FilePath = this->GetStartingContext().FilePath; + mf.RecordPolicies(f.Policies); + 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; } // create a function blocker - cmMacroFunctionBlocker* f = new cmMacroFunctionBlocker(); - cmAppend(f->Args, args); - this->Makefile->AddFunctionBlocker(f); + { + auto fb = cm::make_unique<cmMacroFunctionBlocker>(); + cmAppend(fb->Args, args); + status.GetMakefile().AddFunctionBlocker(std::move(fb)); + } return true; } diff --git a/Source/cmMacroCommand.h b/Source/cmMacroCommand.h index b54ed66..25091ea 100644 --- a/Source/cmMacroCommand.h +++ b/Source/cmMacroCommand.h @@ -8,40 +8,10 @@ #include <string> #include <vector> -#include "cmCommand.h" -#include "cmFunctionBlocker.h" -#include "cmListFileCache.h" - class cmExecutionStatus; -class cmMakefile; - -class cmMacroFunctionBlocker : public cmFunctionBlocker -{ -public: - bool IsFunctionBlocked(const cmListFileFunction&, cmMakefile& mf, - cmExecutionStatus&) override; - bool ShouldRemove(const cmListFileFunction&, cmMakefile& mf) override; - - std::vector<std::string> Args; - std::vector<cmListFileFunction> Functions; - int Depth = 0; -}; /// Starts macro() ... endmacro() block -class cmMacroCommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - cmCommand* Clone() override { return new 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 d2637f3..2474383 100644 --- a/Source/cmMakeDirectoryCommand.h +++ b/Source/cmMakeDirectoryCommand.h @@ -8,11 +8,9 @@ #include <string> #include <vector> -#include "cmCommand.h" - class cmExecutionStatus; -/** \class cmMakeDirectoryCommand +/** * \brief Specify auxiliary source code directories. * * cmMakeDirectoryCommand specifies source code directories @@ -21,20 +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. - */ - cmCommand* Clone() override { return new 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 e0f69cb..f101cdc 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -9,14 +9,13 @@ #include <cstring> #include <ctype.h> #include <iterator> -#include <memory> // IWYU pragma: keep +#include <memory> #include <sstream> #include <stdio.h> #include <stdlib.h> #include <utility> #include "cmAlgorithms.h" -#include "cmCommand.h" #include "cmCommandArgumentParserHelper.h" #include "cmCustomCommand.h" #include "cmCustomCommandLines.h" @@ -24,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" @@ -48,7 +48,7 @@ #include "cmConfigure.h" // IWYU pragma: keep -#ifdef CMAKE_BUILD_WITH_CMAKE +#ifndef CMAKE_BOOTSTRAP # include "cmVariableWatch.h" #endif @@ -98,7 +98,7 @@ cmMakefile::cmMakefile(cmGlobalGenerator* globalGenerator, // cmListFileCache in the top level if necessary. this->CheckCMP0000 = false; -#if defined(CMAKE_BUILD_WITH_CMAKE) +#if !defined(CMAKE_BOOTSTRAP) this->AddSourceGroup("", "^.*$"); this->AddSourceGroup("Source Files", CM_SOURCE_REGEX); this->AddSourceGroup("Header Files", CM_HEADER_REGEX); @@ -118,8 +118,6 @@ cmMakefile::~cmMakefile() cmDeleteAll(this->SourceFiles); cmDeleteAll(this->Tests); cmDeleteAll(this->ImportedTargetsOwned); - cmDeleteAll(this->FinalPassCommands); - cmDeleteAll(this->FunctionBlockers); cmDeleteAll(this->EvaluationFiles); } @@ -324,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. @@ -356,6 +360,11 @@ private: cmMakefile* Makefile; }; +void cmMakefile::OnExecuteCommand(std::function<void()> callback) +{ + this->ExecuteCommandCallback = std::move(callback); +} + bool cmMakefile::ExecuteCommand(const cmListFileFunction& lff, cmExecutionStatus& status) { @@ -367,6 +376,10 @@ bool cmMakefile::ExecuteCommand(const cmListFileFunction& lff, return result; } + if (this->ExecuteCommandCallback) { + this->ExecuteCommandCallback(); + } + // Place this call on the call stack. cmMakefileCall stack_manager(this, lff, status); static_cast<void>(stack_manager); @@ -390,12 +403,8 @@ bool cmMakefile::ExecuteCommand(const cmListFileFunction& lff, } // Lookup the command prototype. - if (cmCommand* proto = + if (cmState::Command command = this->GetState()->GetCommandByExactName(lff.Name.Lower)) { - // Clone the prototype. - std::unique_ptr<cmCommand> pcmd(proto->Clone()); - pcmd->SetMakefile(this); - // Decide whether to invoke the command. if (!cmSystemTools::GetFatalErrorOccured()) { // if trace is enabled, print out invoke information @@ -403,29 +412,25 @@ bool cmMakefile::ExecuteCommand(const cmListFileFunction& lff, this->PrintCommandTrace(lff); } // Try invoking the command. - bool invokeSucceeded = pcmd->InvokeInitialPass(lff.Arguments, status); + bool invokeSucceeded = command(lff.Arguments, status); bool hadNestedError = status.GetNestedError(); if (!invokeSucceeded || hadNestedError) { if (!hadNestedError) { // The command invocation requested that we report an error. std::string const error = - std::string(lff.Name.Original) + " " + pcmd->GetError(); + std::string(lff.Name.Original) + " " + status.GetError(); this->IssueMessage(MessageType::FATAL_ERROR, error); } result = false; if (this->GetCMakeInstance()->GetWorkingMode() != cmake::NORMAL_MODE) { cmSystemTools::SetFatalErrorOccured(); } - } else if (pcmd->HasFinalPass()) { - // use the command - this->FinalPassCommands.push_back(pcmd.release()); } } } 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(); @@ -567,8 +572,9 @@ void cmMakefile::IncludeScope::EnforceCMP0011() bool cmMakefile::ReadDependentFile(const std::string& filename, bool noPolicyScope) { - this->AddDefinition("CMAKE_PARENT_LIST_FILE", - this->GetDefinition("CMAKE_CURRENT_LIST_FILE")); + if (const char* def = this->GetDefinition("CMAKE_CURRENT_LIST_FILE")) { + this->AddDefinition("CMAKE_PARENT_LIST_FILE", def); + } std::string filenametoread = cmSystemTools::CollapseFullPath( filename, this->GetCurrentSourceDirectory()); @@ -651,9 +657,9 @@ void cmMakefile::ReadListFile(cmListFile const& listFile, this->GetSafeDefinition("CMAKE_PARENT_LIST_FILE"); std::string currentFile = this->GetSafeDefinition("CMAKE_CURRENT_LIST_FILE"); - this->AddDefinition("CMAKE_CURRENT_LIST_FILE", filenametoread.c_str()); + this->AddDefinition("CMAKE_CURRENT_LIST_FILE", filenametoread); this->AddDefinition("CMAKE_CURRENT_LIST_DIR", - cmSystemTools::GetFilenamePath(filenametoread).c_str()); + cmSystemTools::GetFilenamePath(filenametoread)); this->MarkVariableAsUsed("CMAKE_PARENT_LIST_FILE"); this->MarkVariableAsUsed("CMAKE_CURRENT_LIST_FILE"); @@ -662,7 +668,7 @@ void cmMakefile::ReadListFile(cmListFile const& listFile, // Run the parsed commands. const size_t numberFunctions = listFile.Functions.size(); for (size_t i = 0; i < numberFunctions; ++i) { - cmExecutionStatus status; + cmExecutionStatus status(*this); this->ExecuteCommand(listFile.Functions[i], status); if (cmSystemTools::GetFatalErrorOccured()) { break; @@ -674,10 +680,10 @@ void cmMakefile::ReadListFile(cmListFile const& listFile, } this->CheckForUnusedVariables(); - this->AddDefinition("CMAKE_PARENT_LIST_FILE", currentParentFile.c_str()); - this->AddDefinition("CMAKE_CURRENT_LIST_FILE", currentFile.c_str()); + this->AddDefinition("CMAKE_PARENT_LIST_FILE", currentParentFile); + this->AddDefinition("CMAKE_CURRENT_LIST_FILE", currentFile); this->AddDefinition("CMAKE_CURRENT_LIST_DIR", - cmSystemTools::GetFilenamePath(currentFile).c_str()); + cmSystemTools::GetFilenamePath(currentFile)); this->MarkVariableAsUsed("CMAKE_PARENT_LIST_FILE"); this->MarkVariableAsUsed("CMAKE_CURRENT_LIST_FILE"); this->MarkVariableAsUsed("CMAKE_CURRENT_LIST_DIR"); @@ -769,6 +775,11 @@ struct file_not_persistent }; } +void cmMakefile::AddFinalAction(FinalAction action) +{ + this->FinalActions.push_back(std::move(action)); +} + void cmMakefile::FinalPass() { // do all the variable expansions here @@ -776,8 +787,8 @@ void cmMakefile::FinalPass() // give all the commands a chance to do something // after the file has been parsed before generation - for (cmCommand* fpCommand : this->FinalPassCommands) { - fpCommand->FinalPass(); + for (FinalAction& action : this->FinalActions) { + action(*this); } // go through all configured files and see which ones still exist. @@ -1176,10 +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 += "/"; - force += utilityName; + std::string force = + cmStrCat(this->GetCurrentBinaryDirectory(), "/CMakeFiles/", utilityName); std::vector<std::string> forced; forced.push_back(force); std::string no_main_dependency; @@ -1343,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; - cmSystemTools::ExpandListArgument(cdefs, defs); + std::vector<std::string> defs = cmExpandedList(cdefs); // Recompose the list without the definition. std::vector<std::string>::const_iterator defEnd = @@ -1385,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); } @@ -1420,7 +1428,7 @@ void cmMakefile::PushFunctionScope(std::string const& fileName, this->PushLoopBlockBarrier(); -#if defined(CMAKE_BUILD_WITH_CMAKE) +#if !defined(CMAKE_BOOTSTRAP) this->GetGlobalGenerator()->GetFileLockPool().PushFunctionScope(); #endif @@ -1437,7 +1445,7 @@ void cmMakefile::PopFunctionScope(bool reportError) this->PopFunctionBlockerBarrier(reportError); -#if defined(CMAKE_BUILD_WITH_CMAKE) +#if !defined(CMAKE_BOOTSTRAP) this->GetGlobalGenerator()->GetFileLockPool().PopFunctionScope(); #endif @@ -1479,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( @@ -1492,7 +1500,7 @@ public: this->Snapshot = this->GG->GetCMakeInstance()->GetCurrentSnapshot(); this->GG->GetCMakeInstance()->SetCurrentSnapshot(this->Snapshot); this->GG->SetCurrentMakefile(mf); -#if defined(CMAKE_BUILD_WITH_CMAKE) +#if !defined(CMAKE_BOOTSTRAP) this->GG->GetFileLockPool().PushFileScope(); #endif } @@ -1501,7 +1509,7 @@ public: { this->Makefile->PopFunctionBlockerBarrier(this->ReportError); this->Makefile->PopSnapshot(this->ReportError); -#if defined(CMAKE_BUILD_WITH_CMAKE) +#if !defined(CMAKE_BOOTSTRAP) this->GG->GetFileLockPool().PopFileScope(); #endif this->GG->SetCurrentMakefile(this->CurrentMakefile); @@ -1523,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 @@ -1535,12 +1542,12 @@ 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)); - this->AddDefinition("CMAKE_PARENT_LIST_FILE", currentStart.c_str()); + this->AddDefinition("CMAKE_PARENT_LIST_FILE", currentStart); cmListFile listFile; if (!listFile.ParseFile(currentStart.c_str(), this->GetMessenger(), @@ -1578,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; } @@ -1647,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); } @@ -1690,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); } } @@ -1788,26 +1794,27 @@ void cmMakefile::AddSystemIncludeDirectories(const std::set<std::string>& incs) } } -void cmMakefile::AddDefinition(const std::string& name, const char* value) +void cmMakefile::AddDefinition(const std::string& name, cm::string_view value) { - if (!value) { - return; - } - if (this->VariableInitialized(name)) { this->LogUnused("changing definition", name); } this->StateSnapshot.SetDefinition(name, value); -#ifdef CMAKE_BUILD_WITH_CMAKE +#ifndef CMAKE_BOOTSTRAP cmVariableWatch* vv = this->GetVariableWatch(); if (vv) { vv->VariableAccessed(name, cmVariableWatch::VARIABLE_MODIFIED_ACCESS, - value, this); + value.data(), this); } #endif } +void cmMakefile::AddDefinitionBool(const std::string& name, bool value) +{ + this->AddDefinition(name, value ? "ON" : "OFF"); +} + void cmMakefile::AddCacheDefinition(const std::string& name, const char* value, const char* doc, cmStateEnums::CacheEntryType type, @@ -1831,10 +1838,10 @@ void cmMakefile::AddCacheDefinition(const std::string& name, const char* value, std::vector<std::string> files; nvalue = value ? value : ""; - cmSystemTools::ExpandListArgument(nvalue, files); + cmExpandList(nvalue, files); nvalue.clear(); for (cc = 0; cc < files.size(); cc++) { - if (!cmSystemTools::IsOff(files[cc])) { + if (!cmIsOff(files[cc])) { files[cc] = cmSystemTools::CollapseFullPath(files[cc]); } if (cc > 0) { @@ -1853,23 +1860,6 @@ void cmMakefile::AddCacheDefinition(const std::string& name, const char* value, this->StateSnapshot.RemoveDefinition(name); } -void cmMakefile::AddDefinition(const std::string& name, bool value) -{ - if (this->VariableInitialized(name)) { - this->LogUnused("changing definition", name); - } - - this->StateSnapshot.SetDefinition(name, value ? "ON" : "OFF"); - -#ifdef CMAKE_BUILD_WITH_CMAKE - cmVariableWatch* vv = this->GetVariableWatch(); - if (vv) { - vv->VariableAccessed(name, cmVariableWatch::VARIABLE_MODIFIED_ACCESS, - value ? "ON" : "OFF", this); - } -#endif -} - void cmMakefile::CheckForUnusedVariables() const { if (!this->WarnUnused) { @@ -1914,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())) { @@ -1932,7 +1921,7 @@ void cmMakefile::RemoveDefinition(const std::string& name) this->LogUnused("unsetting", name); } this->StateSnapshot.RemoveDefinition(name); -#ifdef CMAKE_BUILD_WITH_CMAKE +#ifndef CMAKE_BOOTSTRAP cmVariableWatch* vv = this->GetVariableWatch(); if (vv) { vv->VariableAccessed(name, cmVariableWatch::VARIABLE_REMOVED_ACCESS, @@ -1963,8 +1952,7 @@ void cmMakefile::AddGlobalLinkInformation(cmTarget& target) } if (const char* linkLibsProp = this->GetProperty("LINK_LIBRARIES")) { - std::vector<std::string> linkLibs; - cmSystemTools::ExpandListArgument(linkLibsProp, linkLibs); + std::vector<std::string> linkLibs = cmExpandedList(linkLibsProp); for (std::vector<std::string>::iterator j = linkLibs.begin(); j != linkLibs.end(); ++j) { @@ -2090,7 +2078,7 @@ cmSourceFile* cmMakefile::GetSourceFileWithOutput( return nullptr; } -#if defined(CMAKE_BUILD_WITH_CMAKE) +#if !defined(CMAKE_BOOTSTRAP) cmSourceGroup* cmMakefile::GetSourceGroup( const std::vector<std::string>& name) const { @@ -2186,8 +2174,7 @@ cmSourceGroup* cmMakefile::GetOrCreateSourceGroup(const std::string& name) if (delimiter == nullptr) { delimiter = "\\"; } - return this->GetOrCreateSourceGroup( - cmSystemTools::tokenize(name, delimiter)); + return this->GetOrCreateSourceGroup(cmTokenize(name, delimiter)); } /** @@ -2292,8 +2279,7 @@ void cmMakefile::ExpandVariablesCMP0019() } if (const char* linkLibsProp = this->GetProperty("LINK_LIBRARIES")) { - std::vector<std::string> linkLibs; - cmSystemTools::ExpandListArgument(linkLibsProp, linkLibs); + std::vector<std::string> linkLibs = cmExpandedList(linkLibsProp); for (std::vector<std::string>::iterator l = linkLibs.begin(); l != linkLibs.end(); ++l) { @@ -2336,7 +2322,7 @@ void cmMakefile::ExpandVariablesCMP0019() bool cmMakefile::IsOn(const std::string& name) const { const char* value = this->GetDefinition(name); - return cmSystemTools::IsOn(value); + return cmIsOn(value); } bool cmMakefile::IsSet(const std::string& name) const @@ -2350,7 +2336,7 @@ bool cmMakefile::IsSet(const std::string& name) const return false; } - if (cmSystemTools::IsNOTFOUND(value)) { + if (cmIsNOTFOUND(value)) { return false; } @@ -2472,7 +2458,7 @@ bool cmMakefile::IsDefinitionSet(const std::string& name) const if (!def) { def = this->GetState()->GetInitializedCacheValue(name); } -#ifdef CMAKE_BUILD_WITH_CMAKE +#ifndef CMAKE_BOOTSTRAP if (cmVariableWatch* vv = this->GetVariableWatch()) { if (!def) { vv->VariableAccessed( @@ -2489,7 +2475,7 @@ const std::string* cmMakefile::GetDef(const std::string& name) const if (!def) { def = this->GetState()->GetInitializedCacheValue(name); } -#ifdef CMAKE_BUILD_WITH_CMAKE +#ifndef CMAKE_BOOTSTRAP cmVariableWatch* vv = this->GetVariableWatch(); if (vv && !this->SuppressSideEffects) { bool const watch_function_executed = @@ -2608,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 "); @@ -2679,7 +2665,7 @@ MessageType cmMakefile::ExpandVariablesInStringOld( if (const char* val = this->GetDefinition(var)) { // Store the value in the output escaping as requested. if (escapeQuotes) { - source.append(cmSystemTools::EscapeQuotes(val)); + source.append(cmEscapeQuotes(val)); } else { source.append(val); } @@ -2824,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); } @@ -2843,7 +2827,7 @@ MessageType cmMakefile::ExpandVariablesInStringNew( // Get the string we're meant to append to. if (value) { if (escapeQuotes) { - varresult = cmSystemTools::EscapeQuotes(value); + varresult = cmEscapeQuotes(value); } else { varresult = value; } @@ -2969,7 +2953,7 @@ MessageType cmMakefile::ExpandVariablesInStringNew( } if (escapeQuotes) { - varresult = cmSystemTools::EscapeQuotes(varresult); + varresult = cmEscapeQuotes(varresult); } // Skip over the variable. result.append(last, in - last); @@ -3062,7 +3046,7 @@ std::string cmMakefile::GetConfigurations(std::vector<std::string>& configs, if (this->GetGlobalGenerator()->IsMultiConfig()) { if (const char* configTypes = this->GetDefinition("CMAKE_CONFIGURATION_TYPES")) { - cmSystemTools::ExpandListArgument(configTypes, configs); + cmExpandList(configTypes, configs); } return ""; } @@ -3077,19 +3061,11 @@ bool cmMakefile::IsFunctionBlocked(const cmListFileFunction& lff, cmExecutionStatus& status) { // if there are no blockers get out of here - if (this->FunctionBlockers.begin() == this->FunctionBlockers.end()) { + if (this->FunctionBlockers.empty()) { return false; } - // loop over all function blockers to see if any block this command - // evaluate in reverse, this is critical for balanced IF statements etc - for (cmFunctionBlocker* pos : cmReverseRange(this->FunctionBlockers)) { - if (pos->IsFunctionBlocked(lff, *this, status)) { - return true; - } - } - - return false; + return this->FunctionBlockers.top()->IsFunctionBlocked(lff, status); } void cmMakefile::PushFunctionBlockerBarrier() @@ -3103,8 +3079,9 @@ void cmMakefile::PopFunctionBlockerBarrier(bool reportError) FunctionBlockersType::size_type barrier = this->FunctionBlockerBarriers.back(); while (this->FunctionBlockers.size() > barrier) { - std::unique_ptr<cmFunctionBlocker> fb(this->FunctionBlockers.back()); - this->FunctionBlockers.pop_back(); + std::unique_ptr<cmFunctionBlocker> fb( + std::move(this->FunctionBlockers.top())); + this->FunctionBlockers.pop(); if (reportError) { // Report the context in which the unclosed block was opened. cmListFileContext const& lfc = fb->GetStartingContext(); @@ -3186,7 +3163,7 @@ bool cmMakefile::ExpandArguments(std::vector<cmListFileArgument> const& inArgs, if (i.Delim == cmListFileArgument::Quoted) { outArgs.push_back(value); } else { - cmSystemTools::ExpandListArgument(value, outArgs); + cmExpandList(value, outArgs); } } return !cmSystemTools::GetFatalErrorOccured(); @@ -3218,8 +3195,7 @@ bool cmMakefile::ExpandArguments( if (i.Delim == cmListFileArgument::Quoted) { outArgs.emplace_back(value, true); } else { - std::vector<std::string> stringArgs; - cmSystemTools::ExpandListArgument(value, stringArgs); + std::vector<std::string> stringArgs = cmExpandedList(value); for (std::string const& stringArg : stringArgs) { outArgs.emplace_back(stringArg, false); } @@ -3228,54 +3204,25 @@ bool cmMakefile::ExpandArguments( return !cmSystemTools::GetFatalErrorOccured(); } -void cmMakefile::AddFunctionBlocker(cmFunctionBlocker* fb) +void cmMakefile::AddFunctionBlocker(std::unique_ptr<cmFunctionBlocker> fb) { if (!this->ExecutionStatusStack.empty()) { // Record the context in which the blocker is created. fb->SetStartingContext(this->GetExecutionContext()); } - this->FunctionBlockers.push_back(fb); + this->FunctionBlockers.push(std::move(fb)); } -std::unique_ptr<cmFunctionBlocker> cmMakefile::RemoveFunctionBlocker( - cmFunctionBlocker* fb, const cmListFileFunction& lff) +std::unique_ptr<cmFunctionBlocker> cmMakefile::RemoveFunctionBlocker() { - // Find the function blocker stack barrier for the current scope. - // We only remove a blocker whose index is not less than the barrier. - FunctionBlockersType::size_type barrier = 0; - if (!this->FunctionBlockerBarriers.empty()) { - barrier = this->FunctionBlockerBarriers.back(); - } + assert(!this->FunctionBlockers.empty()); + assert(this->FunctionBlockerBarriers.empty() || + this->FunctionBlockers.size() > this->FunctionBlockerBarriers.back()); - // Search for the function blocker whose scope this command ends. - for (FunctionBlockersType::size_type i = this->FunctionBlockers.size(); - i > barrier; --i) { - std::vector<cmFunctionBlocker*>::iterator pos = - this->FunctionBlockers.begin() + (i - 1); - if (*pos == fb) { - // Warn if the arguments do not match, but always remove. - if (!(*pos)->ShouldRemove(lff, *this)) { - cmListFileContext const& lfc = fb->GetStartingContext(); - cmListFileContext closingContext = - cmListFileContext::FromCommandContext(lff, lfc.FilePath); - std::ostringstream e; - /* clang-format off */ - e << "A logical block opening on the line\n" - << " " << lfc << "\n" - << "closes on the line\n" - << " " << closingContext << "\n" - << "with mis-matching arguments."; - /* clang-format on */ - this->IssueMessage(MessageType::AUTHOR_WARNING, e.str()); - } - cmFunctionBlocker* b = *pos; - this->FunctionBlockers.erase(pos); - return std::unique_ptr<cmFunctionBlocker>(b); - } - } - - return std::unique_ptr<cmFunctionBlocker>(); + auto b = std::move(this->FunctionBlockers.top()); + this->FunctionBlockers.pop(); + return b; } std::string const& cmMakefile::GetHomeDirectory() const @@ -3290,20 +3237,18 @@ std::string const& cmMakefile::GetHomeOutputDirectory() const void cmMakefile::SetScriptModeFile(std::string const& scriptfile) { - this->AddDefinition("CMAKE_SCRIPT_MODE_FILE", scriptfile.c_str()); + this->AddDefinition("CMAKE_SCRIPT_MODE_FILE", scriptfile); } void cmMakefile::SetArgcArgv(const std::vector<std::string>& args) { - std::ostringstream strStream; - strStream << args.size(); - this->AddDefinition("CMAKE_ARGC", strStream.str().c_str()); + this->AddDefinition("CMAKE_ARGC", std::to_string(args.size())); // this->MarkVariableAsUsed("CMAKE_ARGC"); for (unsigned int t = 0; t < args.size(); ++t) { std::ostringstream tmpStream; tmpStream << "CMAKE_ARGV" << t; - this->AddDefinition(tmpStream.str(), args[t].c_str()); + this->AddDefinition(tmpStream.str(), args[t]); // this->MarkVariableAsUsed(tmpStream.str().c_str()); } } @@ -3375,7 +3320,7 @@ void cmMakefile::AddTargetObject(std::string const& tgtName, cmSourceFile* sf = this->GetOrCreateSource(objFile, true); sf->SetObjectLibrary(tgtName); sf->SetProperty("EXTERNAL_OBJECT", "1"); -#if defined(CMAKE_BUILD_WITH_CMAKE) +#if !defined(CMAKE_BOOTSTRAP) this->SourceGroups[this->ObjectLibrariesSourceGroupIndex].AddGroupFile( sf->GetFullPath()); #endif @@ -3384,8 +3329,9 @@ void cmMakefile::AddTargetObject(std::string const& tgtName, void cmMakefile::EnableLanguage(std::vector<std::string> const& lang, bool optional) { - this->AddDefinition("CMAKE_CFG_INTDIR", - this->GetGlobalGenerator()->GetCMakeCFGIntDir()); + if (const char* def = this->GetGlobalGenerator()->GetCMakeCFGIntDir()) { + this->AddDefinition("CMAKE_CFG_INTDIR", def); + } // If RC is explicitly listed we need to do it after other languages. // On some platforms we enable RC implicitly while enabling others. // Do not let that look like recursive enable_language(RC). @@ -3556,7 +3502,7 @@ cmGlobalGenerator* cmMakefile::GetGlobalGenerator() const return this->GlobalGenerator; } -#ifdef CMAKE_BUILD_WITH_CMAKE +#ifndef CMAKE_BOOTSTRAP cmVariableWatch* cmMakefile::GetVariableWatch() const { if (this->GetCMakeInstance() && @@ -3604,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; - cmSystemTools::ExpandListArgument(cmakeModulePath, modulePath); + std::vector<std::string> modulePath = cmExpandedList(cmakeModulePath); // Look through the possible module directories. for (std::string itempl : modulePath) { @@ -3620,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(); @@ -3697,7 +3641,7 @@ void cmMakefile::ConfigureString(const std::string& input, std::string& output, // Replace #cmakedefine instances. if (this->cmDefineRegex.find(line)) { const char* def = this->GetDefinition(this->cmDefineRegex.match(2)); - if (!cmSystemTools::IsOff(def)) { + if (!cmIsOff(def)) { const std::string indentation = this->cmDefineRegex.match(1); cmSystemTools::ReplaceString(line, "#" + indentation + "cmakedefine", "#" + indentation + "define"); @@ -3713,7 +3657,7 @@ void cmMakefile::ConfigureString(const std::string& input, std::string& output, cmSystemTools::ReplaceString(line, "#" + indentation + "cmakedefine01", "#" + indentation + "define"); output += line; - if (!cmSystemTools::IsOff(def)) { + if (!cmIsOff(def)) { output += " 1"; } else { output += " 0"; @@ -3788,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 " + @@ -3877,7 +3820,7 @@ const char* cmMakefile::GetProperty(const std::string& prop, bool chain) const bool cmMakefile::GetPropertyAsBool(const std::string& prop) const { - return cmSystemTools::IsOn(this->GetProperty(prop)); + return cmIsOn(this->GetProperty(prop)); } std::vector<std::string> cmMakefile::GetPropertyKeys() const @@ -3930,15 +3873,13 @@ void cmMakefile::AddCMakeDependFilesFromUser() { std::vector<std::string> deps; if (const char* deps_str = this->GetProperty("CMAKE_CONFIGURE_DEPENDS")) { - cmSystemTools::ExpandListArgument(deps_str, deps); + cmExpandList(deps_str, deps); } for (std::string const& dep : deps) { 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); } } @@ -3978,14 +3919,14 @@ void cmMakefile::PushScope() this->GetState()->CreateVariableScopeSnapshot(this->StateSnapshot); this->PushLoopBlockBarrier(); -#if defined(CMAKE_BUILD_WITH_CMAKE) +#if !defined(CMAKE_BOOTSTRAP) this->GetGlobalGenerator()->GetFileLockPool().PushFunctionScope(); #endif } void cmMakefile::PopScope() { -#if defined(CMAKE_BUILD_WITH_CMAKE) +#if !defined(CMAKE_BOOTSTRAP) this->GetGlobalGenerator()->GetFileLockPool().PopFunctionScope(); #endif @@ -4009,7 +3950,7 @@ void cmMakefile::RaiseScope(const std::string& var, const char* varDef) return; } -#ifdef CMAKE_BUILD_WITH_CMAKE +#ifndef CMAKE_BOOTSTRAP cmVariableWatch* vv = this->GetVariableWatch(); if (vv) { vv->VariableAccessed(var, cmVariableWatch::VARIABLE_MODIFIED_ACCESS, @@ -4059,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); @@ -4237,7 +4178,7 @@ void cmMakefile::StoreMatches(cmsys::RegularExpression& re) std::string const& m = re.match(i); if (!m.empty()) { std::string const& var = matchVariables[i]; - this->AddDefinition(var, m.c_str()); + this->AddDefinition(var, m); this->MarkVariableAsUsed(var); highest = static_cast<char>('0' + i); } @@ -4267,7 +4208,7 @@ bool cmMakefile::PolicyOptionalWarningEnabled(std::string const& var) { // Check for an explicit CMAKE_POLICY_WARNING_CMP<NNNN> setting. if (const char* val = this->GetDefinition(var)) { - return cmSystemTools::IsOn(val); + return cmIsOn(val); } // Enable optional policy warnings with --debug-output, --trace, // or --trace-expand. @@ -4300,7 +4241,7 @@ bool cmMakefile::SetPolicy(cmPolicies::PolicyID id, // Deprecate old policies, especially those that require a lot // of code to maintain the old behavior. - if (status == cmPolicies::OLD && id <= cmPolicies::CMP0066 && + if (status == cmPolicies::OLD && id <= cmPolicies::CMP0067 && !(this->GetCMakeInstance()->GetIsInTryCompile() && ( // Policies set by cmCoreTryCompile::TryCompileCode. @@ -4424,10 +4365,8 @@ bool cmMakefile::AddRequiredTargetFeature(cmTarget* target, return false; } - std::vector<std::string> availableFeatures; - cmSystemTools::ExpandListArgument(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\"" @@ -4549,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; } @@ -4633,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; } @@ -4694,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; - cmSystemTools::ExpandListArgument(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; - cmSystemTools::ExpandListArgument(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; - cmSystemTools::ExpandListArgument(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; - cmSystemTools::ExpandListArgument(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; - cmSystemTools::ExpandListArgument(propCxx20, props); - needCxx20 = std::find(props.begin(), props.end(), feature) != props.end(); + std::vector<std::string> props = cmExpandedList(propCxx20); + needCxx20 = cmContains(props, feature); } } @@ -4818,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; - cmSystemTools::ExpandListArgument(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; - cmSystemTools::ExpandListArgument(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; - cmSystemTools::ExpandListArgument(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 d223347..dcc4e77 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -7,8 +7,9 @@ #include "cmsys/RegularExpression.hxx" #include <deque> +#include <functional> #include <map> -#include <memory> // IWYU pragma: keep +#include <memory> #include <set> #include <stack> #include <stddef.h> @@ -16,6 +17,8 @@ #include <unordered_map> #include <vector> +#include "cm_string_view.hxx" + #include "cmAlgorithms.h" #include "cmListFileCache.h" #include "cmMessageType.h" @@ -24,13 +27,13 @@ #include "cmSourceFileLocationKind.h" #include "cmStateSnapshot.h" #include "cmStateTypes.h" +#include "cmStringAlgorithms.h" #include "cmTarget.h" -#if defined(CMAKE_BUILD_WITH_CMAKE) +#if !defined(CMAKE_BOOTSTRAP) # include "cmSourceGroup.h" #endif -class cmCommand; class cmCompiledGeneratorExpression; class cmCustomCommandLines; class cmExecutionStatus; @@ -95,7 +98,7 @@ public: /** * Add a function blocker to this makefile */ - void AddFunctionBlocker(cmFunctionBlocker* fb); + void AddFunctionBlocker(std::unique_ptr<cmFunctionBlocker> fb); /// @return whether we are processing the top CMakeLists.txt file. bool IsRootMakefile() const; @@ -104,8 +107,7 @@ public: * Remove the function blocker whose scope ends with the given command. * This returns ownership of the function blocker object. */ - std::unique_ptr<cmFunctionBlocker> RemoveFunctionBlocker( - cmFunctionBlocker* fb, const cmListFileFunction& lff); + std::unique_ptr<cmFunctionBlocker> RemoveFunctionBlocker(); /** * Try running cmake and building a file. This is used for dynalically @@ -125,6 +127,13 @@ public: bool EnforceUniqueName(std::string const& name, std::string& msg, bool isCustom = false) const; + using FinalAction = std::function<void(cmMakefile&)>; + + /** + * Register an action that is executed during FinalPass + */ + void AddFinalAction(FinalAction action); + /** * Perform FinalPass, Library dependency analysis etc before output of the * makefile. @@ -132,7 +141,7 @@ public: void ConfigureFinalPass(); /** - * run the final pass on all commands. + * run all FinalActions. */ void FinalPass(); @@ -256,18 +265,17 @@ public: * Add a variable definition to the build. This variable * can be used in CMake to refer to lists, directories, etc. */ - void AddDefinition(const std::string& name, const char* value); + void AddDefinition(const std::string& name, cm::string_view value); + /** + * Add bool variable definition to the build. + */ + void AddDefinitionBool(const std::string& name, bool); //! Add a definition to this makefile and the global cmake cache. void AddCacheDefinition(const std::string& name, const char* value, const char* doc, cmStateEnums::CacheEntryType type, bool force = false); /** - * Add bool variable definition to the build. - */ - void AddDefinition(const std::string& name, bool); - - /** * Remove a variable definition from the build. This is not valid * for cache entries, and will only affect the current makefile. */ @@ -495,7 +503,7 @@ public: */ bool CanIWriteThisFile(std::string const& fileName) const; -#if defined(CMAKE_BUILD_WITH_CMAKE) +#if !defined(CMAKE_BOOTSTRAP) /** * Get the vector source groups. */ @@ -619,6 +627,11 @@ public: void PrintCommandTrace(const cmListFileFunction& lff) const; /** + * Set a callback that is invoked whenever ExecuteCommand is called. + */ + void OnExecuteCommand(std::function<void()> callback); + + /** * Execute a single CMake command. Returns true if the command * succeeded or false if it failed. */ @@ -636,7 +649,7 @@ public: * Get the variable watch. This is used to determine when certain variables * are accessed. */ -#ifdef CMAKE_BUILD_WITH_CMAKE +#ifndef CMAKE_BOOTSTRAP cmVariableWatch* GetVariableWatch() const; #endif @@ -932,12 +945,12 @@ protected: // Track the value of the computed DEFINITIONS property. std::string DefineFlagsOrig; -#if defined(CMAKE_BUILD_WITH_CMAKE) +#if !defined(CMAKE_BOOTSTRAP) std::vector<cmSourceGroup> SourceGroups; size_t ObjectLibrariesSourceGroupIndex; #endif - std::vector<cmCommand*> FinalPassCommands; + std::vector<FinalAction> FinalActions; cmGlobalGenerator* GlobalGenerator; bool IsFunctionBlocked(const cmListFileFunction& lff, cmExecutionStatus& status); @@ -955,7 +968,10 @@ private: bool EnforceUniqueDir(const std::string& srcPath, const std::string& binPath) const; - typedef std::vector<cmFunctionBlocker*> FunctionBlockersType; + std::function<void()> ExecuteCommandCallback; + using FunctionBlockerPtr = std::unique_ptr<cmFunctionBlocker>; + using FunctionBlockersType = + std::stack<FunctionBlockerPtr, std::vector<FunctionBlockerPtr>>; FunctionBlockersType FunctionBlockers; std::vector<FunctionBlockersType::size_type> FunctionBlockerBarriers; void PushFunctionBlockerBarrier(); @@ -986,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 6b9b9c7..7bc05b1 100644 --- a/Source/cmMakefileExecutableTargetGenerator.cxx +++ b/Source/cmMakefileExecutableTargetGenerator.cxx @@ -2,13 +2,14 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmMakefileExecutableTargetGenerator.h" -#include <memory> // IWYU pragma: keep #include <set> #include <sstream> #include <string> #include <utility> #include <vector> +#include "cm_memory.hxx" + #include "cmAlgorithms.h" #include "cmGeneratedFileStream.h" #include "cmGeneratorTarget.h" @@ -25,6 +26,7 @@ #include "cmStateDirectory.h" #include "cmStateSnapshot.h" #include "cmStateTypes.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" cmMakefileExecutableTargetGenerator::cmMakefileExecutableTargetGenerator( @@ -81,7 +83,7 @@ void cmMakefileExecutableTargetGenerator::WriteRuleFiles() void cmMakefileExecutableTargetGenerator::WriteDeviceExecutableRule( bool relink) { -#ifdef CMAKE_BUILD_WITH_CMAKE +#ifndef CMAKE_BOOTSTRAP const bool requiresDeviceLinking = requireDeviceLinking( *this->GeneratorTarget, *this->LocalGenerator, this->ConfigName); if (!requiresDeviceLinking) { @@ -109,14 +111,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); } @@ -128,9 +129,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)); } @@ -163,7 +163,7 @@ void cmMakefileExecutableTargetGenerator::WriteDeviceExecutableRule( const std::string linkRuleVar = "CMAKE_CUDA_DEVICE_LINK_EXECUTABLE"; const std::string linkRule = this->GetLinkRule(linkRuleVar); std::vector<std::string> commands1; - cmSystemTools::ExpandListArgument(linkRule, real_link_commands); + cmExpandList(linkRule, real_link_commands); bool useResponseFileForObjects = this->CheckUseResponseFileForObjects(linkLanguage); @@ -232,8 +232,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( @@ -242,7 +241,7 @@ void cmMakefileExecutableTargetGenerator::WriteDeviceExecutableRule( // Expand placeholders in the commands. rulePlaceholderExpander->SetTargetImpLib(targetOutputReal); for (std::string& real_link_command : real_link_commands) { - real_link_command = launcher + real_link_command; + real_link_command = cmStrCat(launcher, real_link_command); rulePlaceholderExpander->ExpandRuleVariables(this->LocalGenerator, real_link_command, vars); } @@ -295,14 +294,13 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) if (this->GeneratorTarget->IsAppBundleOnApple()) { this->OSXBundleGenerator->CreateAppBundle(targetNames.Output, outpath); } - outpath += "/"; + outpath += '/'; std::string outpathImp; if (relink) { - outpath = this->Makefile->GetCurrentBinaryDirectory(); - outpath += "/CMakeFiles"; - outpath += "/CMakeRelink.dir"; + outpath = cmStrCat(this->Makefile->GetCurrentBinaryDirectory(), + "/CMakeFiles/CMakeRelink.dir"); cmSystemTools::MakeDirectory(outpath); - outpath += "/"; + outpath += '/'; if (!targetNames.ImportLibrary.empty()) { outpathImp = outpath; } @@ -312,7 +310,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) outpathImp = this->GeneratorTarget->GetDirectory( this->ConfigName, cmStateEnums::ImportLibraryArtifact); cmSystemTools::MakeDirectory(outpathImp); - outpathImp += "/"; + outpathImp += '/'; } } @@ -323,7 +321,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) std::string pdbOutputPath = this->GeneratorTarget->GetPDBDirectory(this->ConfigName); cmSystemTools::MakeDirectory(pdbOutputPath); - pdbOutputPath += "/"; + pdbOutputPath += '/'; std::string targetFullPath = outpath + targetNames.Output; std::string targetFullPathReal = outpath + targetNames.Real; @@ -370,10 +368,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); } @@ -396,9 +392,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)); } @@ -482,20 +477,18 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) // Construct the main link rule. std::vector<std::string> real_link_commands; - std::string linkRuleVar = "CMAKE_"; - linkRuleVar += linkLanguage; - linkRuleVar += "_LINK_EXECUTABLE"; + std::string linkRuleVar = this->GeneratorTarget->GetCreateRuleVariable( + linkLanguage, this->ConfigName); std::string linkRule = this->GetLinkRule(linkRuleVar); std::vector<std::string> commands1; - cmSystemTools::ExpandListArgument(linkRule, real_link_commands); + cmExpandList(linkRule, real_link_commands); 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)) { - cmSystemTools::ExpandListArgument(rule, real_link_commands); + cmExpandList(rule, real_link_commands); } } @@ -590,10 +583,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 +595,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( @@ -612,7 +604,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) // Expand placeholders in the commands. rulePlaceholderExpander->SetTargetImpLib(targetOutPathImport); for (std::string& real_link_command : real_link_commands) { - real_link_command = launcher + real_link_command; + real_link_command = cmStrCat(launcher, real_link_command); rulePlaceholderExpander->ExpandRuleVariables(this->LocalGenerator, real_link_command, vars); } @@ -639,10 +631,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 b9f7c6d..252279f 100644 --- a/Source/cmMakefileLibraryTargetGenerator.cxx +++ b/Source/cmMakefileLibraryTargetGenerator.cxx @@ -2,13 +2,14 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmMakefileLibraryTargetGenerator.h" -#include <memory> // IWYU pragma: keep #include <set> #include <sstream> #include <stddef.h> #include <utility> #include <vector> +#include "cm_memory.hxx" + #include "cmAlgorithms.h" #include "cmGeneratedFileStream.h" #include "cmGeneratorTarget.h" @@ -25,6 +26,7 @@ #include "cmStateDirectory.h" #include "cmStateSnapshot.h" #include "cmStateTypes.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" cmMakefileLibraryTargetGenerator::cmMakefileLibraryTargetGenerator( @@ -161,9 +163,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); @@ -196,9 +197,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); @@ -219,9 +219,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); @@ -234,7 +233,7 @@ void cmMakefileLibraryTargetGenerator::WriteFrameworkRules(bool relink) void cmMakefileLibraryTargetGenerator::WriteDeviceLibraryRules( const std::string& linkRuleVar, bool relink) { -#ifdef CMAKE_BUILD_WITH_CMAKE +#ifndef CMAKE_BOOTSTRAP // TODO: Merge the methods that call this method to avoid // code duplication. std::vector<std::string> commands; @@ -262,12 +261,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); } @@ -358,8 +358,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( @@ -368,11 +367,11 @@ void cmMakefileLibraryTargetGenerator::WriteDeviceLibraryRules( // Construct the main link rule and expand placeholders. rulePlaceholderExpander->SetTargetImpLib(targetOutputReal); std::string linkRule = this->GetLinkRule(linkRuleVar); - cmSystemTools::ExpandListArgument(linkRule, real_link_commands); + cmExpandList(linkRule, real_link_commands); // Expand placeholders. for (std::string& real_link_command : real_link_commands) { - real_link_command = launcher + real_link_command; + real_link_command = cmStrCat(launcher, real_link_command); rulePlaceholderExpander->ExpandRuleVariables(this->LocalGenerator, real_link_command, vars); } @@ -463,30 +462,29 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules( outpath = this->GeneratorTarget->GetDirectory(this->ConfigName); this->OSXBundleGenerator->CreateFramework(this->TargetNames.Output, outpath); - outpath += "/"; + outpath += '/'; } else if (this->GeneratorTarget->IsCFBundleOnApple()) { outpath = this->GeneratorTarget->GetDirectory(this->ConfigName); this->OSXBundleGenerator->CreateCFBundle(this->TargetNames.Output, outpath); - outpath += "/"; + outpath += '/'; } else if (relink) { - outpath = this->Makefile->GetCurrentBinaryDirectory(); - outpath += "/CMakeFiles"; - outpath += "/CMakeRelink.dir"; + outpath = cmStrCat(this->Makefile->GetCurrentBinaryDirectory(), + "/CMakeFiles/CMakeRelink.dir"); cmSystemTools::MakeDirectory(outpath); - outpath += "/"; + outpath += '/'; if (!this->TargetNames.ImportLibrary.empty()) { outpathImp = outpath; } } else { outpath = this->GeneratorTarget->GetDirectory(this->ConfigName); cmSystemTools::MakeDirectory(outpath); - outpath += "/"; + outpath += '/'; if (!this->TargetNames.ImportLibrary.empty()) { outpathImp = this->GeneratorTarget->GetDirectory( this->ConfigName, cmStateEnums::ImportLibraryArtifact); cmSystemTools::MakeDirectory(outpathImp); - outpathImp += "/"; + outpathImp += '/'; } } @@ -535,8 +533,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 "; @@ -640,35 +637,32 @@ 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); if (const char* rule = this->Makefile->GetDefinition(arCreateVar)) { - cmSystemTools::ExpandListArgument(rule, archiveCreateCommands); + 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); if (const char* rule = this->Makefile->GetDefinition(arAppendVar)) { - cmSystemTools::ExpandListArgument(rule, archiveAppendCommands); + 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); if (const char* rule = this->Makefile->GetDefinition(arFinishVar)) { - cmSystemTools::ExpandListArgument(rule, archiveFinishCommands); + cmExpandList(rule, archiveFinishCommands); } } @@ -820,8 +814,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( @@ -878,19 +871,19 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules( } else { // Get the set of commands. std::string linkRule = this->GetLinkRule(linkRuleVar); - cmSystemTools::ExpandListArgument(linkRule, real_link_commands); + 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)); } // Expand placeholders. for (std::string& real_link_command : real_link_commands) { - real_link_command = launcher + real_link_command; + real_link_command = cmStrCat(launcher, real_link_command); rulePlaceholderExpander->ExpandRuleVariables(this->LocalGenerator, real_link_command, vars); } @@ -920,12 +913,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 b3bab4b..f99fe4e 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -2,7 +2,7 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmMakefileTargetGenerator.h" -#include <memory> // IWYU pragma: keep +#include <memory> #include <sstream> #include <stdio.h> #include <utility> @@ -28,6 +28,7 @@ #include "cmStateDirectory.h" #include "cmStateSnapshot.h" #include "cmStateTypes.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmake.h" @@ -48,7 +49,7 @@ cmMakefileTargetGenerator::cmMakefileTargetGenerator(cmGeneratorTarget* target) this->NoRuleMessages = false; if (const char* ruleStatus = cm->GetState()->GetGlobalProperty("RULE_MESSAGES")) { - this->NoRuleMessages = cmSystemTools::IsOff(ruleStatus); + this->NoRuleMessages = cmIsOff(ruleStatus); } MacOSXContentGenerator = new MacOSXContentGeneratorType(this); } @@ -89,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)); @@ -113,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; @@ -130,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; @@ -158,10 +158,9 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules() std::vector<std::string> files; cmGeneratorExpression ge; std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(prop_value); - cmSystemTools::ExpandListArgument( - cge->Evaluate(this->LocalGenerator, config, false, this->GeneratorTarget, - nullptr, nullptr), - files); + cmExpandList(cge->Evaluate(this->LocalGenerator, config, false, + this->GeneratorTarget, nullptr, nullptr), + files); return files; }; @@ -186,7 +185,7 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules() // add custom commands to the clean rules? const char* clean_no_custom = this->Makefile->GetProperty("CLEAN_NO_CUSTOM"); - bool clean = cmSystemTools::IsOff(clean_no_custom); + bool clean = cmIsOff(clean_no_custom); // First generate the object rule files. Save a list of all object // files for this target. @@ -260,8 +259,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 +294,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 +324,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 +359,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 +371,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 +403,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 +440,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 +461,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 +531,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 +555,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 +576,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 +626,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); @@ -679,12 +665,12 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile( } const std::string& compileRule = this->Makefile->GetRequiredDefinition(cmdVar); - cmSystemTools::ExpandListArgument(compileRule, compileCommands); + cmExpandList(compileRule, compileCommands); } else { const std::string cmdVar = "CMAKE_" + lang + "_COMPILE_OBJECT"; const std::string& compileRule = this->Makefile->GetRequiredDefinition(cmdVar); - cmSystemTools::ExpandListArgument(compileRule, compileCommands); + cmExpandList(compileRule, compileCommands); } if (this->Makefile->IsOn("CMAKE_EXPORT_COMPILE_COMMANDS") && @@ -781,8 +767,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; - cmSystemTools::ExpandListArgument(compilerLauncher, args, true); + std::vector<std::string> args = cmExpandedList(compilerLauncher, true); if (!args.empty()) { args[0] = this->LocalGenerator->ConvertToOutputFormat( args[0], cmOutputConverter::SHELL); @@ -798,14 +783,13 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile( const char* val = this->LocalGenerator->GetRuleLauncher( this->GeneratorTarget, "RULE_LAUNCH_COMPILE"); if (val && *val) { - launcher = val; - launcher += " "; + launcher = cmStrCat(val, ' '); } } // Expand placeholders in the commands. for (std::string& compileCommand : compileCommands) { - compileCommand = launcher + compileCommand; + compileCommand = cmStrCat(launcher, compileCommand); rulePlaceholderExpander->ExpandRuleVariables(this->LocalGenerator, compileCommand, vars); } @@ -821,7 +805,7 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile( std::vector<std::string> outputs(1, relativeObj); if (const char* extra_outputs_str = source.GetProperty("OBJECT_OUTPUTS")) { // Register these as extra files to clean. - cmSystemTools::ExpandListArgument(extra_outputs_str, outputs); + cmExpandList(extra_outputs_str, outputs); this->CleanFiles.insert(outputs.begin() + 1, outputs.end()); } @@ -846,20 +830,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; - cmSystemTools::ExpandListArgument(preprocessRule, preprocessCommands); + std::vector<std::string> preprocessCommands = + cmExpandedList(preprocessRule); std::string shellObjI = this->LocalGenerator->ConvertToOutputFormat( objI, cmOutputConverter::SHELL); @@ -878,8 +859,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 +875,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; - cmSystemTools::ExpandListArgument(assemblyRule, assemblyCommands); + std::vector<std::string> assemblyCommands = + cmExpandedList(assemblyRule); std::string shellObjS = this->LocalGenerator->ConvertToOutputFormat( objS, cmOutputConverter::SHELL); @@ -924,8 +903,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 +922,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 +1008,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 +1067,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. @@ -1181,7 +1160,7 @@ void cmMakefileTargetGenerator::WriteObjectDependRules( // shared between the object file and dependency scanning rule. depends.push_back(source.GetFullPath()); if (const char* objectDeps = source.GetProperty("OBJECT_DEPENDS")) { - cmSystemTools::ExpandListArgument(objectDeps, depends); + cmExpandList(objectDeps, depends); } } @@ -1235,8 +1214,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(); @@ -1370,8 +1349,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 +1405,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 +1451,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 +1474,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 +1487,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)); } @@ -1528,7 +1506,7 @@ bool cmMakefileTargetGenerator::CheckUseResponseFileForObjects( "CMAKE_" + l + "_USE_RESPONSE_FILE_FOR_OBJECTS"; if (const char* val = this->Makefile->GetDefinition(responseVar)) { if (*val) { - return cmSystemTools::IsOn(val); + return cmIsOn(val); } } @@ -1567,7 +1545,7 @@ bool cmMakefileTargetGenerator::CheckUseResponseFileForLibraries( "CMAKE_" + l + "_USE_RESPONSE_FILE_FOR_LIBRARIES"; if (const char* val = this->Makefile->GetDefinition(responseVar)) { if (*val) { - return cmSystemTools::IsOn(val); + return cmIsOn(val); } } @@ -1580,9 +1558,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 +1569,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 +1602,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 +1615,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 +1639,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 +1674,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 +1706,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 +1725,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/cmMakefileTargetGenerator.h b/Source/cmMakefileTargetGenerator.h index c570a7c..9eeeed0 100644 --- a/Source/cmMakefileTargetGenerator.h +++ b/Source/cmMakefileTargetGenerator.h @@ -7,6 +7,7 @@ #include <iosfwd> #include <map> +#include <memory> #include <set> #include <string> #include <vector> diff --git a/Source/cmMakefileUtilityTargetGenerator.cxx b/Source/cmMakefileUtilityTargetGenerator.cxx index 4236995..8ed6be5 100644 --- a/Source/cmMakefileUtilityTargetGenerator.cxx +++ b/Source/cmMakefileUtilityTargetGenerator.cxx @@ -7,7 +7,8 @@ #include <utility> #include <vector> -#include "cmAlgorithms.h" +#include "cm_memory.hxx" + #include "cmGeneratedFileStream.h" #include "cmGeneratorTarget.h" #include "cmGlobalUnixMakefileGenerator3.h" 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 5dd198f..de7bf08 100644 --- a/Source/cmMarkAsAdvancedCommand.h +++ b/Source/cmMarkAsAdvancedCommand.h @@ -8,29 +8,14 @@ #include <string> #include <vector> -#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. - */ - cmCommand* Clone() override { return new 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 0c6c76b..ac1957c 100644 --- a/Source/cmMathCommand.h +++ b/Source/cmMathCommand.h @@ -8,28 +8,10 @@ #include <string> #include <vector> -#include "cmCommand.h" - class cmExecutionStatus; /// Mathematical expressions: math(EXPR ...) command. -class cmMathCommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - cmCommand* Clone() override { return new 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 5320ec5..39b40b8 100644 --- a/Source/cmMessageCommand.cxx +++ b/Source/cmMessageCommand.cxx @@ -2,30 +2,28 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmMessageCommand.h" -#include "cmAlgorithms.h" +#include "cmExecutionStatus.h" #include "cmMakefile.h" #include "cmMessageType.h" #include "cmMessenger.h" #include "cmRange.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmake.h" #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(); auto type = MessageType::MESSAGE; - auto status = false; auto fatal = false; auto level = cmake::LogLevel::LOG_UNDEFINED; if (*i == "SEND_ERROR") { @@ -42,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 { @@ -55,28 +54,24 @@ bool cmMessageCommand::InitialPass(std::vector<std::string> const& args, } ++i; } else if (*i == "STATUS") { - status = true; level = cmake::LogLevel::LOG_STATUS; ++i; } else if (*i == "VERBOSE") { - status = true; level = cmake::LogLevel::LOG_VERBOSE; ++i; } else if (*i == "DEBUG") { - status = true; level = cmake::LogLevel::LOG_DEBUG; ++i; } else if (*i == "TRACE") { - status = true; 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 { @@ -94,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); @@ -105,17 +100,45 @@ bool cmMessageCommand::InitialPass(std::vector<std::string> const& args, auto message = cmJoin(cmMakeRange(i, args.cend()), ""); - if (type != MessageType::MESSAGE) { - // we've overridden the message type, above, so display it directly - cmMessenger* m = this->Makefile->GetMessenger(); - m->DisplayMessage(type, message, this->Makefile->GetBacktrace()); - } else { - if (status) { - this->Makefile->DisplayStatus(message, -1); - } else { + if (cmake::LogLevel::LOG_NOTICE <= level) { + // 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(status.GetMakefile().GetSafeDefinition( + "CMAKE_MESSAGE_INDENT")), + ""); + // Make every line of the `message` indented + // NOTE Can't reuse `cmDocumentationFormatter::PrintPreformatted` + // here cuz it appends `\n` to the EOM ;-( + cmSystemTools::ReplaceString(message, "\n", "\n" + indent); + message = indent + message; + } + + switch (level) { + case cmake::LogLevel::LOG_ERROR: + case cmake::LogLevel::LOG_WARNING: + // we've overridden the message type, above, so display it directly + status.GetMakefile().GetMessenger()->DisplayMessage( + type, message, status.GetMakefile().GetBacktrace()); + break; + + case cmake::LogLevel::LOG_NOTICE: cmSystemTools::Message(message); - } + break; + + case cmake::LogLevel::LOG_STATUS: + case cmake::LogLevel::LOG_VERBOSE: + case cmake::LogLevel::LOG_DEBUG: + case cmake::LogLevel::LOG_TRACE: + status.GetMakefile().DisplayStatus(message, -1); + break; + + default: + assert("Unexpected log level! Review the `cmMessageCommand.cxx`." && + false); + break; } + if (fatal) { cmSystemTools::SetFatalErrorOccured(); } diff --git a/Source/cmMessageCommand.h b/Source/cmMessageCommand.h index 819ebda..7d544c4 100644 --- a/Source/cmMessageCommand.h +++ b/Source/cmMessageCommand.h @@ -8,28 +8,13 @@ #include <string> #include <vector> -#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. - */ - cmCommand* Clone() override { return new 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/cmMessenger.cxx b/Source/cmMessenger.cxx index 1d790e2..af83478 100644 --- a/Source/cmMessenger.cxx +++ b/Source/cmMessenger.cxx @@ -2,11 +2,11 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmMessenger.h" -#include "cmAlgorithms.h" #include "cmDocumentationFormatter.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" -#if defined(CMAKE_BUILD_WITH_CMAKE) +#if !defined(CMAKE_BOOTSTRAP) # include "cmsys/SystemInformation.hxx" #endif @@ -100,14 +100,13 @@ void displayMessage(MessageType t, std::ostringstream& msg) "it."; } else if (t == MessageType::AUTHOR_ERROR) { msg << "This error is for project developers. Use -Wno-error=dev to " - "suppress " - "it."; + "suppress it."; } // Add a terminating blank line. msg << "\n"; -#if defined(CMAKE_BUILD_WITH_CMAKE) +#if !defined(CMAKE_BOOTSTRAP) // Add a C++ stack trace to internal errors. if (t == MessageType::INTERNAL_ERROR) { std::string stack = cmsys::SystemInformation::GetProgramStack(0, 0); diff --git a/Source/cmNewLineStyle.cxx b/Source/cmNewLineStyle.cxx index 3f6523e..1ff741e 100644 --- a/Source/cmNewLineStyle.cxx +++ b/Source/cmNewLineStyle.cxx @@ -41,7 +41,7 @@ bool cmNewLineStyle::ReadFromArguments(const std::vector<std::string>& args, return true; } -const std::string cmNewLineStyle::GetCharacters() const +std::string cmNewLineStyle::GetCharacters() const { switch (NewLineStyle) { case Invalid: diff --git a/Source/cmNewLineStyle.h b/Source/cmNewLineStyle.h index f1a7bc6..ab9002e 100644 --- a/Source/cmNewLineStyle.h +++ b/Source/cmNewLineStyle.h @@ -30,7 +30,7 @@ public: bool ReadFromArguments(const std::vector<std::string>& args, std::string& errorString); - const std::string GetCharacters() const; + std::string GetCharacters() const; private: Style NewLineStyle = Invalid; diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx index f65abc8..17a5527 100644 --- a/Source/cmNinjaNormalTargetGenerator.cxx +++ b/Source/cmNinjaNormalTargetGenerator.cxx @@ -6,11 +6,12 @@ #include <assert.h> #include <iterator> #include <map> -#include <memory> // IWYU pragma: keep #include <set> #include <sstream> #include <utility> +#include "cm_memory.hxx" + #include "cmAlgorithms.h" #include "cmCustomCommand.h" // IWYU pragma: keep #include "cmCustomCommandGenerator.h" @@ -32,6 +33,7 @@ #include "cmStateDirectory.h" #include "cmStateSnapshot.h" #include "cmStateTypes.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" cmNinjaNormalTargetGenerator::cmNinjaNormalTargetGenerator( @@ -85,6 +87,7 @@ void cmNinjaNormalTargetGenerator::Generate() this->WriteLinkStatement(); } + // Find ADDITIONAL_CLEAN_FILES this->AdditionalCleanFiles(); } @@ -216,8 +219,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( @@ -226,7 +228,7 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkRule(bool useResponseFile) // Rule for linking library/executable. std::vector<std::string> linkCmds = this->ComputeDeviceLinkCmd(); for (std::string& linkCmd : linkCmds) { - linkCmd = launcher + linkCmd; + linkCmd = cmStrCat(launcher, linkCmd); rulePlaceholderExpander->ExpandRuleVariables(this->GetLocalGenerator(), linkCmd, vars); } @@ -237,16 +239,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); @@ -280,8 +276,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"; @@ -355,8 +350,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( @@ -365,7 +359,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile) // Rule for linking library/executable. std::vector<std::string> linkCmds = this->ComputeLinkCmd(); for (std::string& linkCmd : linkCmds) { - linkCmd = launcher + linkCmd; + linkCmd = cmStrCat(launcher, linkCmd); rulePlaceholderExpander->ExpandRuleVariables(this->GetLocalGenerator(), linkCmd, vars); } @@ -378,16 +372,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); } @@ -438,12 +426,12 @@ std::vector<std::string> cmNinjaNormalTargetGenerator::ComputeDeviceLinkCmd() case cmStateEnums::MODULE_LIBRARY: { const std::string cudaLinkCmd( this->GetMakefile()->GetDefinition("CMAKE_CUDA_DEVICE_LINK_LIBRARY")); - cmSystemTools::ExpandListArgument(cudaLinkCmd, linkCmds); + cmExpandList(cudaLinkCmd, linkCmds); } break; case cmStateEnums::EXECUTABLE: { const std::string cudaLinkCmd(this->GetMakefile()->GetDefinition( "CMAKE_CUDA_DEVICE_LINK_EXECUTABLE")); - cmSystemTools::ExpandListArgument(cudaLinkCmd, linkCmds); + cmExpandList(cudaLinkCmd, linkCmds); } break; default: break; @@ -465,19 +453,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; } } - cmSystemTools::ExpandListArgument(linkCmdStr, linkCmds); + 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( @@ -500,26 +488,24 @@ 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()); std::string const& linkCmd = mf->GetRequiredDefinition(linkCmdVar); - cmSystemTools::ExpandListArgument(linkCmd, linkCmds); + 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()); std::string const& linkCmd = mf->GetRequiredDefinition(linkCmdVar); - cmSystemTools::ExpandListArgument(linkCmd, linkCmds); + cmExpandList(linkCmd, linkCmds); } #ifdef __APPLE__ // On macOS ranlib truncates the fractional part of the static archive @@ -588,10 +574,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; @@ -726,13 +710,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. @@ -755,10 +735,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); @@ -965,7 +943,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 }; @@ -987,11 +966,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); @@ -1036,8 +1015,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 2139a45..3d3d80d 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -8,10 +8,11 @@ #include <assert.h> #include <iterator> #include <map> -#include <memory> // IWYU pragma: keep #include <ostream> #include <utility> +#include "cm_memory.hxx" + #include "cmAlgorithms.h" #include "cmComputeLinkInformation.h" #include "cmCustomCommandGenerator.h" @@ -30,6 +31,7 @@ #include "cmSourceFile.h" #include "cmState.h" #include "cmStateTypes.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmake.h" @@ -217,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, @@ -372,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; } @@ -414,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( @@ -486,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 = @@ -527,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 = ""; @@ -544,26 +541,21 @@ 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"; - cmSystemTools::ExpandListArgument( - this->GetMakefile()->GetRequiredDefinition(ppVar), ppCmds); + std::string ppVar = cmStrCat("CMAKE_", lang, "_PREPROCESS_SOURCE"); + cmExpandList(this->GetMakefile()->GetRequiredDefinition(ppVar), ppCmds); } for (std::string& i : ppCmds) { - i = launcher + i; + i = cmStrCat(launcher, i); rulePlaceholderExpander->ExpandRuleVariables(this->GetLocalGenerator(), i, ppVars); } // 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"; } @@ -572,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); } @@ -594,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); } @@ -619,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 = ""; @@ -647,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"; @@ -684,11 +659,11 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang) cmdVar = "CMAKE_CUDA_COMPILE_WHOLE_COMPILATION"; } const std::string& compileCmd = mf->GetRequiredDefinition(cmdVar); - cmSystemTools::ExpandListArgument(compileCmd, compileCmds); + cmExpandList(compileCmd, compileCmds); } else { const std::string cmdVar = "CMAKE_" + lang + "_COMPILE_OBJECT"; const std::string& compileCmd = mf->GetRequiredDefinition(cmdVar); - cmSystemTools::ExpandListArgument(compileCmd, compileCmds); + cmExpandList(compileCmd, compileCmds); } // See if we need to use a compiler launcher like ccache or distcc @@ -714,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 @@ -751,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; - cmSystemTools::ExpandListArgument(compilerLauncher, args, true); + std::vector<std::string> args = cmExpandedList(compilerLauncher, true); if (!args.empty()) { args[0] = this->LocalGenerator->ConvertToOutputFormat( args[0], cmOutputConverter::SHELL); @@ -768,7 +741,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang) } for (std::string& i : compileCmds) { - i = launcher + i; + i = cmStrCat(launcher, i); rulePlaceholderExpander->ExpandRuleVariables(this->GetLocalGenerator(), i, vars); } @@ -776,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); } @@ -863,11 +832,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)); } @@ -909,8 +876,8 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements() this->GetBuildFileStream() << "\n"; if (!this->SwiftOutputMap.empty()) { - std::string const mapFilePath = this->ConvertToNinjaPath( - this->GeneratorTarget->GetSupportDirectory() + "/output-file-map.json"); + std::string const mapFilePath = + this->GeneratorTarget->GetSupportDirectory() + "/output-file-map.json"; std::string const targetSwiftDepsPath = [this]() -> std::string { cmGeneratorTarget const* target = this->GeneratorTarget; if (const char* name = target->GetProperty("Swift_DEPENDENCIES_FILE")) { @@ -944,8 +911,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"; @@ -966,9 +932,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) { @@ -996,8 +961,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement( objBuild.ExplicitDeps.push_back(sourceFileName); if (const char* objectDeps = source->GetProperty("OBJECT_DEPENDS")) { - std::vector<std::string> depList = - cmSystemTools::ExpandedListArgument(objectDeps); + std::vector<std::string> depList = cmExpandedList(objectDeps); for (std::string& odi : depList) { if (cmSystemTools::FileIsFullPath(odi)) { odi = cmSystemTools::CollapseFullPath(odi); @@ -1150,7 +1114,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement( if (const char* objectOutputs = source->GetProperty("OBJECT_OUTPUTS")) { cmNinjaBuild build("phony"); build.Comment = "Additional output files."; - build.Outputs = cmSystemTools::ExpandedListArgument(objectOutputs); + build.Outputs = cmExpandedList(objectOutputs); std::transform(build.Outputs.begin(), build.Outputs.end(), build.Outputs.begin(), MapToNinjaPath()); build.ExplicitDeps = objBuild.Outputs; @@ -1299,12 +1263,12 @@ void cmNinjaTargetGenerator::ExportObjectCompileCommand( } const std::string& compileCmd = this->GetMakefile()->GetRequiredDefinition(cmdVar); - cmSystemTools::ExpandListArgument(compileCmd, compileCmds); + cmExpandList(compileCmd, compileCmds); } else { const std::string cmdVar = "CMAKE_" + language + "_COMPILE_OBJECT"; const std::string& compileCmd = this->GetMakefile()->GetRequiredDefinition(cmdVar); - cmSystemTools::ExpandListArgument(compileCmd, compileCmds); + cmExpandList(compileCmd, compileCmds); } std::unique_ptr<cmRulePlaceholderExpander> rulePlaceholderExpander( @@ -1331,11 +1295,10 @@ void cmNinjaTargetGenerator::AdditionalCleanFiles() { cmGeneratorExpression ge; auto cge = ge.Parse(prop_value); - cmSystemTools::ExpandListArgument( - cge->Evaluate(lg, - this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"), - false, this->GeneratorTarget, nullptr, nullptr), - cleanFiles); + cmExpandList(cge->Evaluate( + lg, this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"), + false, this->GeneratorTarget, nullptr, nullptr), + cleanFiles); } std::string const& binaryDir = lg->GetCurrentBinaryDirectory(); cmGlobalNinjaGenerator* gg = lg->GetGlobalNinjaGenerator(); @@ -1384,9 +1347,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/cmNinjaTargetGenerator.h b/Source/cmNinjaTargetGenerator.h index 3055e18..a99d8e7 100644 --- a/Source/cmNinjaTargetGenerator.h +++ b/Source/cmNinjaTargetGenerator.h @@ -13,7 +13,7 @@ #include "cmOSXBundleGenerator.h" #include <map> -#include <memory> // IWYU pragma: keep +#include <memory> #include <set> #include <string> #include <vector> diff --git a/Source/cmNinjaUtilityTargetGenerator.cxx b/Source/cmNinjaUtilityTargetGenerator.cxx index 1225cbd..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,15 +37,15 @@ void cmNinjaUtilityTargetGenerator::Generate() cmLocalNinjaGenerator* lg = this->GetLocalGenerator(); cmGeneratorTarget* genTarget = this->GetGeneratorTarget(); - std::string utilCommandName = lg->GetCurrentBinaryDirectory(); - utilCommandName += "/CMakeFiles"; - utilCommandName += "/"; - 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; { @@ -135,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 52f63a3..a0a0989 100644 --- a/Source/cmOptionCommand.cxx +++ b/Source/cmOptionCommand.cxx @@ -4,36 +4,35 @@ #include <sstream> -#include "cmAlgorithms.h" +#include "cmExecutionStatus.h" #include "cmMakefile.h" #include "cmMessageType.h" #include "cmPolicies.h" #include "cmState.h" #include "cmStateSnapshot.h" #include "cmStateTypes.h" -#include "cmSystemTools.h" - -class cmExecutionStatus; +#include "cmStringAlgorithms.h" // 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; @@ -54,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,13 +66,13 @@ bool cmOptionCommand::InitialPass(std::vector<std::string> const& args, if (args.size() == 3) { initialValue = args[2]; } - bool init = cmSystemTools::IsOn(initialValue); - this->Makefile->AddCacheDefinition(args[0], init ? "ON" : "OFF", - args[1].c_str(), cmStateEnums::BOOL); + bool init = cmIsOn(initialValue); + 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) @@ -81,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 34e0e6f..cbd1cb8 100644 --- a/Source/cmOptionCommand.h +++ b/Source/cmOptionCommand.h @@ -8,29 +8,13 @@ #include <string> #include <vector> -#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. - */ - cmCommand* Clone() override { return new 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 585db42..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" @@ -13,6 +14,7 @@ #include <assert.h> #include <functional> #include <sstream> +#include <vector> /* Directory ordering computation. @@ -116,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. @@ -228,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/cmOutputConverter.cxx b/Source/cmOutputConverter.cxx index 7d88b08..bf516e3 100644 --- a/Source/cmOutputConverter.cxx +++ b/Source/cmOutputConverter.cxx @@ -6,10 +6,10 @@ #include <assert.h> #include <ctype.h> #include <set> -#include <string.h> #include <vector> #include "cmState.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" cmOutputConverter::cmOutputConverter(cmStateSnapshot const& snapshot) @@ -38,10 +38,10 @@ std::string cmOutputConverter::ConvertToOutputForExisting( return this->ConvertToOutputFormat(remote, format); } -std::string cmOutputConverter::ConvertToOutputFormat(const std::string& source, +std::string cmOutputConverter::ConvertToOutputFormat(cm::string_view source, OutputFormat output) const { - std::string result = source; + std::string result(source); // Convert it to an output path. if (output == SHELL || output == WATCOMQUOTE) { result = this->ConvertDirectorySeparatorsForShell(source); @@ -53,9 +53,9 @@ std::string cmOutputConverter::ConvertToOutputFormat(const std::string& source, } std::string cmOutputConverter::ConvertDirectorySeparatorsForShell( - const std::string& source) const + cm::string_view source) const { - std::string result = source; + std::string result(source); // For the MSYS shell convert drive letters to posix paths, so // that c:/some/path becomes /c/some/path. This is needed to // avoid problems with the shell path translation. @@ -71,33 +71,21 @@ std::string cmOutputConverter::ConvertDirectorySeparatorsForShell( return result; } -static bool cmOutputConverterIsShellOperator(const std::string& str) +static bool cmOutputConverterIsShellOperator(cm::string_view str) { - static std::set<std::string> shellOperators; - if (shellOperators.empty()) { - shellOperators.insert("<"); - shellOperators.insert(">"); - shellOperators.insert("<<"); - shellOperators.insert(">>"); - shellOperators.insert("|"); - shellOperators.insert("||"); - shellOperators.insert("&&"); - shellOperators.insert("&>"); - shellOperators.insert("1>"); - shellOperators.insert("2>"); - shellOperators.insert("2>&1"); - shellOperators.insert("1>&2"); - } - return shellOperators.count(str) > 0; + static std::set<cm::string_view> const shellOperators{ + "<", ">", "<<", ">>", "|", "||", "&&", "&>", "1>", "2>", "2>&1", "1>&2" + }; + return (shellOperators.count(str) != 0); } -std::string cmOutputConverter::EscapeForShell(const std::string& str, +std::string cmOutputConverter::EscapeForShell(cm::string_view str, bool makeVars, bool forEcho, bool useWatcomQuote) const { // Do not escape shell operators. if (cmOutputConverterIsShellOperator(str)) { - return str; + return std::string(str); } // Compute the flags for the target shell environment. @@ -129,46 +117,44 @@ std::string cmOutputConverter::EscapeForShell(const std::string& str, flags |= Shell_Flag_IsUnix; } - return Shell__GetArgument(str.c_str(), flags); + return Shell__GetArgument(str, flags); } -std::string cmOutputConverter::EscapeForCMake(const std::string& str) +std::string cmOutputConverter::EscapeForCMake(cm::string_view str) { // Always double-quote the argument to take care of most escapes. std::string result = "\""; - for (const char* c = str.c_str(); *c; ++c) { - if (*c == '"') { + for (const char c : str) { + if (c == '"') { // Escape the double quote to avoid ending the argument. result += "\\\""; - } else if (*c == '$') { + } else if (c == '$') { // Escape the dollar to avoid expanding variables. result += "\\$"; - } else if (*c == '\\') { + } else if (c == '\\') { // Escape the backslash to avoid other escapes. result += "\\\\"; } else { // Other characters will be parsed correctly. - result += *c; + result += c; } } result += "\""; return result; } -std::string cmOutputConverter::EscapeWindowsShellArgument(const char* arg, +std::string cmOutputConverter::EscapeWindowsShellArgument(cm::string_view arg, int shell_flags) { return Shell__GetArgument(arg, shell_flags); } cmOutputConverter::FortranFormat cmOutputConverter::GetFortranFormat( - const char* value) + cm::string_view value) { FortranFormat format = FortranFormatNone; - if (value && *value) { - std::vector<std::string> fmt; - cmSystemTools::ExpandListArgument(value, fmt); - for (std::string const& fi : fmt) { + if (!value.empty()) { + for (std::string const& fi : cmExpandedList(value)) { if (fi == "FIXED") { format = FortranFormatFixed; } @@ -180,6 +166,15 @@ cmOutputConverter::FortranFormat cmOutputConverter::GetFortranFormat( return format; } +cmOutputConverter::FortranFormat cmOutputConverter::GetFortranFormat( + const char* value) +{ + if (!value) { + return FortranFormatNone; + } + return GetFortranFormat(cm::string_view(value)); +} + void cmOutputConverter::SetLinkScriptShell(bool linkScriptShell) { this->LinkScriptShell = linkScriptShell; @@ -225,12 +220,12 @@ use the caret character itself (^), use two in a row (^^). */ /* Some helpers to identify character classes */ -static int Shell__CharIsWhitespace(char c) +static bool Shell__CharIsWhitespace(char c) { return ((c == ' ') || (c == '\t')); } -static int Shell__CharNeedsQuotesOnUnix(char c) +static bool Shell__CharNeedsQuotesOnUnix(char c) { return ((c == '\'') || (c == '`') || (c == ';') || (c == '#') || (c == '&') || (c == '$') || (c == '(') || (c == ')') || (c == '~') || @@ -238,51 +233,52 @@ static int Shell__CharNeedsQuotesOnUnix(char c) (c == '\\')); } -static int Shell__CharNeedsQuotesOnWindows(char c) +static bool Shell__CharNeedsQuotesOnWindows(char c) { return ((c == '\'') || (c == '#') || (c == '&') || (c == '<') || (c == '>') || (c == '|') || (c == '^')); } -static int Shell__CharIsMakeVariableName(char c) +static bool Shell__CharIsMakeVariableName(char c) { return c && (c == '_' || isalpha((static_cast<int>(c)))); } -int cmOutputConverter::Shell__CharNeedsQuotes(char c, int flags) +bool cmOutputConverter::Shell__CharNeedsQuotes(char c, int flags) { /* On Windows the built-in command shell echo never needs quotes. */ if (!(flags & Shell_Flag_IsUnix) && (flags & Shell_Flag_EchoWindows)) { - return 0; + return false; } /* On all platforms quotes are needed to preserve whitespace. */ if (Shell__CharIsWhitespace(c)) { - return 1; + return true; } if (flags & Shell_Flag_IsUnix) { /* On UNIX several special characters need quotes to preserve them. */ if (Shell__CharNeedsQuotesOnUnix(c)) { - return 1; + return true; } } else { /* On Windows several special characters need quotes to preserve them. */ if (Shell__CharNeedsQuotesOnWindows(c)) { - return 1; + return true; } } - return 0; + return false; } -const char* cmOutputConverter::Shell__SkipMakeVariables(const char* c) +cm::string_view::iterator cmOutputConverter::Shell__SkipMakeVariables( + cm::string_view::iterator c, cm::string_view::iterator end) { - while (*c == '$' && *(c + 1) == '(') { - const char* skip = c + 2; - while (Shell__CharIsMakeVariableName(*skip)) { + while ((c != end && (c + 1) != end) && (*c == '$' && *(c + 1) == '(')) { + cm::string_view::iterator skip = c + 2; + while ((skip != end) && Shell__CharIsMakeVariableName(*skip)) { ++skip; } - if (*skip == ')') { + if ((skip != end) && *skip == ')') { c = skip + 1; } else { break; @@ -314,63 +310,60 @@ flag later when we understand applications of this better. */ #define KWSYS_SYSTEM_SHELL_QUOTE_MAKE_VARIABLES 0 -int cmOutputConverter::Shell__ArgumentNeedsQuotes(const char* in, int flags) +bool cmOutputConverter::Shell__ArgumentNeedsQuotes(cm::string_view in, + int flags) { /* The empty string needs quotes. */ - if (!*in) { - return 1; + if (in.empty()) { + return true; } /* Scan the string for characters that require quoting. */ - { - const char* c; - for (c = in; *c; ++c) { - /* Look for $(MAKEVAR) syntax if requested. */ - if (flags & Shell_Flag_AllowMakeVariables) { + for (cm::string_view::iterator cit = in.begin(), cend = in.end(); + cit != cend; ++cit) { + /* Look for $(MAKEVAR) syntax if requested. */ + if (flags & Shell_Flag_AllowMakeVariables) { #if KWSYS_SYSTEM_SHELL_QUOTE_MAKE_VARIABLES - const char* skip = Shell__SkipMakeVariables(c); - if (skip != c) { - /* We need to quote make variable references to preserve the - string with contents substituted in its place. */ - return 1; - } + cm::string_view::iterator skip = Shell__SkipMakeVariables(cit, cend); + if (skip != cit) { + /* We need to quote make variable references to preserve the + string with contents substituted in its place. */ + return true; + } #else - /* Skip over the make variable references if any are present. */ - c = Shell__SkipMakeVariables(c); + /* Skip over the make variable references if any are present. */ + cit = Shell__SkipMakeVariables(cit, cend); - /* Stop if we have reached the end of the string. */ - if (!*c) { - break; - } -#endif + /* Stop if we have reached the end of the string. */ + if (cit == cend) { + break; } +#endif + } - /* Check whether this character needs quotes. */ - if (Shell__CharNeedsQuotes(*c, flags)) { - return 1; - } + /* Check whether this character needs quotes. */ + if (Shell__CharNeedsQuotes(*cit, flags)) { + return true; } } /* On Windows some single character arguments need quotes. */ - if (flags & Shell_Flag_IsUnix && *in && !*(in + 1)) { - char c = *in; + if (flags & Shell_Flag_IsUnix && in.size() == 1) { + char c = in[0]; if ((c == '?') || (c == '&') || (c == '^') || (c == '|') || (c == '#')) { - return 1; + return true; } } - return 0; + return false; } -std::string cmOutputConverter::Shell__GetArgument(const char* in, int flags) +std::string cmOutputConverter::Shell__GetArgument(cm::string_view in, + int flags) { /* Output will be at least as long as input string. */ std::string out; - out.reserve(strlen(in)); - - /* String iterator. */ - const char* c; + out.reserve(in.size()); /* Keep track of how many backslashes have been encountered in a row. */ int windows_backslashes = 0; @@ -390,14 +383,15 @@ std::string cmOutputConverter::Shell__GetArgument(const char* in, int flags) } /* Scan the string for characters that require escaping or quoting. */ - for (c = in; *c; ++c) { + for (cm::string_view::iterator cit = in.begin(), cend = in.end(); + cit != cend; ++cit) { /* Look for $(MAKEVAR) syntax if requested. */ if (flags & Shell_Flag_AllowMakeVariables) { - const char* skip = Shell__SkipMakeVariables(c); - if (skip != c) { + cm::string_view::iterator skip = Shell__SkipMakeVariables(cit, cend); + if (skip != cit) { /* Copy to the end of the make variable references. */ - while (c != skip) { - out += *c++; + while (cit != skip) { + out += *cit++; } /* The make variable reference eliminates any escaping needed @@ -405,7 +399,7 @@ std::string cmOutputConverter::Shell__GetArgument(const char* in, int flags) windows_backslashes = 0; /* Stop if we have reached the end of the string. */ - if (!*c) { + if (cit == cend) { break; } } @@ -415,7 +409,7 @@ std::string cmOutputConverter::Shell__GetArgument(const char* in, int flags) if (flags & Shell_Flag_IsUnix) { /* On Unix a few special characters need escaping even inside a quoted argument. */ - if (*c == '\\' || *c == '"' || *c == '`' || *c == '$') { + if (*cit == '\\' || *cit == '"' || *cit == '`' || *cit == '$') { /* This character needs a backslash to escape it. */ out += '\\'; } @@ -423,10 +417,10 @@ std::string cmOutputConverter::Shell__GetArgument(const char* in, int flags) /* On Windows the built-in command shell echo never needs escaping. */ } else { /* On Windows only backslashes and double-quotes need escaping. */ - if (*c == '\\') { + if (*cit == '\\') { /* Found a backslash. It may need to be escaped later. */ ++windows_backslashes; - } else if (*c == '"') { + } else if (*cit == '"') { /* Found a double-quote. Escape all immediately preceding backslashes. */ while (windows_backslashes > 0) { @@ -444,7 +438,7 @@ std::string cmOutputConverter::Shell__GetArgument(const char* in, int flags) } /* Check whether this character needs escaping for a make tool. */ - if (*c == '$') { + if (*cit == '$') { if (flags & Shell_Flag_Make) { /* In Makefiles a dollar is written $$. The make tool will replace it with just $ before passing it to the shell. */ @@ -461,7 +455,7 @@ std::string cmOutputConverter::Shell__GetArgument(const char* in, int flags) /* Otherwise a dollar is written just $. */ out += '$'; } - } else if (*c == '#') { + } else if (*cit == '#') { if ((flags & Shell_Flag_Make) && (flags & Shell_Flag_WatcomWMake)) { /* In Watcom WMake makefiles a pound is written $#. The make tool will replace it with just # before passing it to the @@ -471,7 +465,7 @@ std::string cmOutputConverter::Shell__GetArgument(const char* in, int flags) /* Otherwise a pound is written just #. */ out += '#'; } - } else if (*c == '%') { + } else if (*cit == '%') { if ((flags & Shell_Flag_VSIDE) || ((flags & Shell_Flag_Make) && ((flags & Shell_Flag_MinGWMake) || (flags & Shell_Flag_NMake)))) { @@ -481,7 +475,7 @@ std::string cmOutputConverter::Shell__GetArgument(const char* in, int flags) /* Otherwise a percent is written just %. */ out += '%'; } - } else if (*c == ';') { + } else if (*cit == ';') { if (flags & Shell_Flag_VSIDE) { /* In a VS IDE a semicolon is written ";". If this is written in an un-quoted argument it starts a quoted segment, @@ -495,7 +489,7 @@ std::string cmOutputConverter::Shell__GetArgument(const char* in, int flags) } } else { /* Store this character. */ - out += *c; + out += *cit; } } diff --git a/Source/cmOutputConverter.h b/Source/cmOutputConverter.h index deca767..671efe7 100644 --- a/Source/cmOutputConverter.h +++ b/Source/cmOutputConverter.h @@ -5,9 +5,10 @@ #include "cmConfigure.h" // IWYU pragma: keep -#include <string> - #include "cmStateSnapshot.h" +#include "cm_string_view.hxx" + +#include <string> class cmState; @@ -22,10 +23,9 @@ public: WATCOMQUOTE, RESPONSE }; - std::string ConvertToOutputFormat(const std::string& source, + std::string ConvertToOutputFormat(cm::string_view source, OutputFormat output) const; - std::string ConvertDirectorySeparatorsForShell( - const std::string& source) const; + std::string ConvertDirectorySeparatorsForShell(cm::string_view source) const; //! for existing files convert to output path and short path if spaces std::string ConvertToOutputForExisting(const std::string& remote, @@ -72,15 +72,15 @@ public: Shell_Flag_IsUnix = (1 << 8) }; - std::string EscapeForShell(const std::string& str, bool makeVars = false, + std::string EscapeForShell(cm::string_view str, bool makeVars = false, bool forEcho = false, bool useWatcomQuote = false) const; - static std::string EscapeForCMake(const std::string& str); + static std::string EscapeForCMake(cm::string_view str); /** Compute an escaped version of the given argument for use in a windows shell. */ - static std::string EscapeWindowsShellArgument(const char* arg, + static std::string EscapeWindowsShellArgument(cm::string_view arg, int shell_flags); enum FortranFormat @@ -89,15 +89,17 @@ public: FortranFormatFixed, FortranFormatFree }; + static FortranFormat GetFortranFormat(cm::string_view value); static FortranFormat GetFortranFormat(const char* value); private: cmState* GetState() const; - static int Shell__CharNeedsQuotes(char c, int flags); - static const char* Shell__SkipMakeVariables(const char* c); - static int Shell__ArgumentNeedsQuotes(const char* in, int flags); - static std::string Shell__GetArgument(const char* in, int flags); + static bool Shell__CharNeedsQuotes(char c, int flags); + static cm::string_view::iterator Shell__SkipMakeVariables( + cm::string_view::iterator begin, cm::string_view::iterator end); + static bool Shell__ArgumentNeedsQuotes(cm::string_view in, int flags); + static std::string Shell__GetArgument(cm::string_view in, int flags); private: cmStateSnapshot StateSnapshot; diff --git a/Source/cmOutputRequiredFilesCommand.cxx b/Source/cmOutputRequiredFilesCommand.cxx index f3276ec..dbb7111 100644 --- a/Source/cmOutputRequiredFilesCommand.cxx +++ b/Source/cmOutputRequiredFilesCommand.cxx @@ -11,6 +11,7 @@ #include "cmGeneratorExpression.h" #include "cmMakefile.h" #include "cmSourceFile.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmTarget.h" @@ -121,8 +122,7 @@ public: std::string incDirs = cmGeneratorExpression::Preprocess( incDirProp, cmGeneratorExpression::StripAllGeneratorExpressions); - std::vector<std::string> includes; - cmSystemTools::ExpandListArgument(incDirs, includes); + std::vector<std::string> includes = cmExpandedList(incDirs); for (std::string& path : includes) { this->Makefile->ExpandVariablesInString(path); @@ -192,10 +192,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; @@ -214,10 +212,8 @@ protected: if (cmSystemTools::FileExists(cxxFile)) { found = true; } - for (std::string path : this->IncludeDirectories) { - path = path + "/"; - path = path + cxxFile; - if (cmSystemTools::FileExists(path)) { + for (std::string const& path : this->IncludeDirectories) { + if (cmSystemTools::FileExists(cmStrCat(path, "/", cxxFile))) { found = true; } } @@ -226,10 +222,8 @@ protected: if (cmSystemTools::FileExists(cxxFile)) { found = true; } - for (std::string path : this->IncludeDirectories) { - path = path + "/"; - path = path + cxxFile; - if (cmSystemTools::FileExists(path)) { + for (std::string const& path : this->IncludeDirectories) { + if (cmSystemTools::FileExists(cmStrCat(path, "/", cxxFile))) { found = true; } } @@ -239,10 +233,8 @@ protected: if (cmSystemTools::FileExists(cxxFile)) { found = true; } - for (std::string path : this->IncludeDirectories) { - path = path + "/"; - path = path + cxxFile; - if (cmSystemTools::FileExists(path)) { + for (std::string const& path : this->IncludeDirectories) { + if (cmSystemTools::FileExists(cmStrCat(path, "/", cxxFile))) { found = true; } } @@ -252,10 +244,8 @@ protected: if (cmSystemTools::FileExists(cxxFile)) { found = true; } - for (std::string path : this->IncludeDirectories) { - path = path + "/"; - path = path + cxxFile; - if (cmSystemTools::FileExists(path)) { + for (std::string const& path : this->IncludeDirectories) { + if (cmSystemTools::FileExists(cmStrCat(path, "/", cxxFile))) { found = true; } } @@ -339,9 +329,9 @@ protected: // try to guess which include path to use for (std::string incpath : this->IncludeDirectories) { if (!incpath.empty() && incpath.back() != '/') { - incpath = incpath + "/"; + incpath += "/"; } - incpath = incpath + path; + incpath += path; if (srcFile->GetFullPath() == incpath) { // set the path to the guessed path info->FullPath = incpath; @@ -420,9 +410,9 @@ protected: for (std::string path : this->IncludeDirectories) { if (!path.empty() && path.back() != '/') { - path = path + "/"; + path += "/"; } - path = path + fname; + path += fname; if (cmSystemTools::FileExists(path, true) && !cmSystemTools::FileIsDirectory(path)) { std::string fp = cmSystemTools::CollapseFullPath(path); @@ -485,9 +475,7 @@ bool cmOutputRequiredFilesCommand::InitialPass( // write them out FILE* fout = cmsys::SystemTools::Fopen(this->OutputFile, "w"); if (!fout) { - std::string err = "Can not open output file: "; - err += this->OutputFile; - this->SetError(err); + this->SetError(cmStrCat("Can not open output file: ", this->OutputFile)); return false; } std::set<cmDependInformation const*> visited; diff --git a/Source/cmOutputRequiredFilesCommand.h b/Source/cmOutputRequiredFilesCommand.h index 09e622b..faffabd 100644 --- a/Source/cmOutputRequiredFilesCommand.h +++ b/Source/cmOutputRequiredFilesCommand.h @@ -10,6 +10,8 @@ #include <string> #include <vector> +#include "cm_memory.hxx" + #include "cmCommand.h" class cmDependInformation; @@ -18,7 +20,10 @@ class cmExecutionStatus; class cmOutputRequiredFilesCommand : public cmCommand { public: - cmCommand* Clone() override { return new cmOutputRequiredFilesCommand; } + std::unique_ptr<cmCommand> Clone() override + { + return cm::make_unique<cmOutputRequiredFilesCommand>(); + } bool InitialPass(std::vector<std::string> const& args, cmExecutionStatus& status) override; diff --git a/Source/cmParseArgumentsCommand.cxx b/Source/cmParseArgumentsCommand.cxx index 5213432..aad9f74 100644 --- a/Source/cmParseArgumentsCommand.cxx +++ b/Source/cmParseArgumentsCommand.cxx @@ -7,16 +7,15 @@ #include <sstream> #include <utility> -#include "cmAlgorithms.h" #include "cmArgumentParser.h" +#include "cmExecutionStatus.h" #include "cmMakefile.h" #include "cmMessageType.h" #include "cmRange.h" +#include "cmStringAlgorithms.h" #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 @@ -75,7 +74,7 @@ static void PassParsedArguments( for (auto const& iter : singleValArgs) { if (!iter.second.empty()) { - makefile.AddDefinition(prefix + iter.first, iter.second.c_str()); + makefile.AddDefinition(prefix + iter.first, iter.second); } else { makefile.RemoveDefinition(prefix + iter.first); } @@ -84,7 +83,7 @@ static void PassParsedArguments( for (auto const& iter : multiValArgs) { if (!iter.second.empty()) { makefile.AddDefinition(prefix + iter.first, - JoinList(iter.second, parseFromArgV).c_str()); + JoinList(iter.second, parseFromArgV)); } else { makefile.RemoveDefinition(prefix + iter.first); } @@ -92,39 +91,38 @@ static void PassParsedArguments( if (!unparsed.empty()) { makefile.AddDefinition(prefix + "UNPARSED_ARGUMENTS", - JoinList(unparsed, parseFromArgV).c_str()); + JoinList(unparsed, parseFromArgV)); } else { makefile.RemoveDefinition(prefix + "UNPARSED_ARGUMENTS"); } if (!keywordsMissingValues.empty()) { - makefile.AddDefinition( - prefix + "KEYWORDS_MISSING_VALUES", - cmJoin(cmMakeRange(keywordsMissingValues), ";").c_str()); + makefile.AddDefinition(prefix + "KEYWORDS_MISSING_VALUES", + cmJoin(cmMakeRange(keywordsMissingValues), ";")); } else { makefile.RemoveDefinition(prefix + "KEYWORDS_MISSING_VALUES"); } } -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,10 +130,10 @@ bool cmParseArgumentsCommand::InitialPass(std::vector<std::string> const& args, } parseFromArgV = true; argIter++; // move past PARSE_ARGV - if (!cmSystemTools::StringToULong(argIter->c_str(), &argvStart)) { - this->Makefile->IssueMessage(MessageType::FATAL_ERROR, - "PARSE_ARGV index '" + *argIter + - "' is not an unsigned integer"); + if (!cmStrToULong(*argIter, &argvStart)) { + status.GetMakefile().IssueMessage(MessageType::FATAL_ERROR, + "PARSE_ARGV index '" + *argIter + + "' is not an unsigned integer"); cmSystemTools::SetFatalErrorOccured(); return true; } @@ -155,24 +153,23 @@ 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; - cmSystemTools::ExpandListArgument(*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 list.clear(); - cmSystemTools::ExpandListArgument(*argIter++, list); + cmExpandList(*argIter++, list); parser.Bind(list, singleValArgs, duplicateKey); // the fourth argument is a (cmake) list of multi argument options list.clear(); - cmSystemTools::ExpandListArgument(*argIter++, list); + cmExpandList(*argIter++, list); parser.Bind(list, multiValArgs, duplicateKey); list.clear(); @@ -180,27 +177,28 @@ bool cmParseArgumentsCommand::InitialPass(std::vector<std::string> const& args, // Flatten ;-lists in the arguments into a single list as was done // by the original function(CMAKE_PARSE_ARGUMENTS). for (; argIter != argEnd; ++argIter) { - cmSystemTools::ExpandListArgument(*argIter, list); + cmExpandList(*argIter, list); } } 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 (!cmSystemTools::StringToULong(argc.c_str(), &count)) { - this->Makefile->IssueMessage(MessageType::FATAL_ERROR, - "PARSE_ARGV called with ARGC='" + argc + - "' that is not an unsigned integer"); + if (!cmStrToULong(argc, &count)) { + 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; } @@ -213,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 b8ba61d..b2e436d 100644 --- a/Source/cmParseArgumentsCommand.h +++ b/Source/cmParseArgumentsCommand.h @@ -8,27 +8,9 @@ #include <string> #include <vector> -#include "cmCommand.h" - class cmExecutionStatus; -/** \class cmParseArgumentsCommand - * - */ -class cmParseArgumentsCommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - cmCommand* Clone() override { return new 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/cmPolicies.cxx b/Source/cmPolicies.cxx index ec40136..d33cd32 100644 --- a/Source/cmPolicies.cxx +++ b/Source/cmPolicies.cxx @@ -1,10 +1,10 @@ #include "cmPolicies.h" -#include "cmAlgorithms.h" #include "cmMakefile.h" #include "cmMessageType.h" #include "cmState.h" #include "cmStateTypes.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmVersion.h" @@ -34,7 +34,7 @@ static bool stringToId(const char* input, cmPolicies::PolicyID& pid) } } long id; - if (!cmSystemTools::StringToLong(input + 3, &id)) { + if (!cmStrToLong(input + 3, &id)) { return false; } if (id >= cmPolicies::CMPCOUNT) { diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h index b705119..92c80bb 100644 --- a/Source/cmPolicies.h +++ b/Source/cmPolicies.h @@ -279,7 +279,18 @@ class cmMakefile; SELECT(POLICY, CMP0094, \ "FindPython3, FindPython2 and FindPyton use " \ "LOCATION for lookup strategy.", \ - 3, 15, 0, cmPolicies::WARN) + 3, 15, 0, cmPolicies::WARN) \ + SELECT(POLICY, CMP0095, \ + "RPATH entries are properly escaped in the intermediary CMake " \ + "install script.", \ + 3, 16, 0, cmPolicies::WARN) \ + SELECT(POLICY, CMP0096, \ + "project() preserves leading zeros in version components.", 3, 16, \ + 0, cmPolicies::WARN) \ + SELECT(POLICY, CMP0097, \ + "ExternalProject_Add with GIT_SUBMODULES \"\" initializes no " \ + "submodules.", \ + 3, 16, 0, cmPolicies::WARN) #define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1) #define CM_FOR_EACH_POLICY_ID(POLICY) \ @@ -307,7 +318,8 @@ class cmMakefile; F(CMP0073) \ F(CMP0076) \ F(CMP0081) \ - F(CMP0083) + F(CMP0083) \ + F(CMP0095) /** \class cmPolicies * \brief Handles changes in CMake behavior and policies diff --git a/Source/cmProjectCommand.cxx b/Source/cmProjectCommand.cxx index 8615ecc..f8c5ada 100644 --- a/Source/cmProjectCommand.cxx +++ b/Source/cmProjectCommand.cxx @@ -3,15 +3,18 @@ #include "cmProjectCommand.h" #include "cmsys/RegularExpression.hxx" +#include <array> +#include <cstdio> #include <functional> +#include <limits> #include <sstream> -#include <stdio.h> +#include <utility> -#include "cmAlgorithms.h" #include "cmMakefile.h" #include "cmMessageType.h" #include "cmPolicies.h" #include "cmStateTypes.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" class cmExecutionStatus; @@ -33,27 +36,21 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args, this->Makefile->SetProjectName(projectName); - std::string bindir = projectName; - bindir += "_BINARY_DIR"; - std::string srcdir = projectName; - srcdir += "_SOURCE_DIR"; - this->Makefile->AddCacheDefinition( - bindir, this->Makefile->GetCurrentBinaryDirectory().c_str(), + projectName + "_BINARY_DIR", + this->Makefile->GetCurrentBinaryDirectory().c_str(), "Value Computed by CMake", cmStateEnums::STATIC); this->Makefile->AddCacheDefinition( - srcdir, this->Makefile->GetCurrentSourceDirectory().c_str(), + projectName + "_SOURCE_DIR", + this->Makefile->GetCurrentSourceDirectory().c_str(), "Value Computed by CMake", cmStateEnums::STATIC); - bindir = "PROJECT_BINARY_DIR"; - srcdir = "PROJECT_SOURCE_DIR"; - - this->Makefile->AddDefinition( - bindir, this->Makefile->GetCurrentBinaryDirectory().c_str()); - this->Makefile->AddDefinition( - srcdir, this->Makefile->GetCurrentSourceDirectory().c_str()); + this->Makefile->AddDefinition("PROJECT_BINARY_DIR", + this->Makefile->GetCurrentBinaryDirectory()); + this->Makefile->AddDefinition("PROJECT_SOURCE_DIR", + this->Makefile->GetCurrentSourceDirectory()); - this->Makefile->AddDefinition("PROJECT_NAME", projectName.c_str()); + this->Makefile->AddDefinition("PROJECT_NAME", projectName); // Set the CMAKE_PROJECT_NAME variable to be the highest-level // project name in the tree. If there are two project commands @@ -63,7 +60,7 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args, // will work. if (!this->Makefile->GetDefinition("CMAKE_PROJECT_NAME") || (this->Makefile->IsRootMakefile())) { - this->Makefile->AddDefinition("CMAKE_PROJECT_NAME", projectName.c_str()); + this->Makefile->AddDefinition("CMAKE_PROJECT_NAME", projectName); this->Makefile->AddCacheDefinition( "CMAKE_PROJECT_NAME", projectName.c_str(), "Value Computed by CMake", cmStateEnums::STATIC); @@ -105,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") { @@ -205,7 +201,7 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args, languages.emplace_back("NONE"); } - cmPolicies::PolicyStatus cmp0048 = + cmPolicies::PolicyStatus const cmp0048 = this->Makefile->GetPolicyStatus(cmPolicies::CMP0048); if (haveVersion) { // Set project VERSION variables to given values @@ -220,64 +216,87 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args, cmsys::RegularExpression vx( R"(^([0-9]+(\.[0-9]+(\.[0-9]+(\.[0-9]+)?)?)?)?$)"); if (!vx.find(version)) { - std::string e = "VERSION \"" + version + "\" format invalid."; + std::string e = R"(VERSION ")" + version + R"(" format invalid.)"; this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e); cmSystemTools::SetFatalErrorOccured(); return true; } - std::string vs; - const char* sep = ""; - char vb[4][64]; - unsigned int v[4] = { 0, 0, 0, 0 }; - int vc = - sscanf(version.c_str(), "%u.%u.%u.%u", &v[0], &v[1], &v[2], &v[3]); - for (int i = 0; i < 4; ++i) { - if (i < vc) { - sprintf(vb[i], "%u", v[i]); - vs += sep; - vs += vb[i]; - sep = "."; - } else { - vb[i][0] = 0; + cmPolicies::PolicyStatus const cmp0096 = + this->Makefile->GetPolicyStatus(cmPolicies::CMP0096); + + constexpr std::size_t MAX_VERSION_COMPONENTS = 4u; + std::string version_string; + std::array<std::string, MAX_VERSION_COMPONENTS> version_components; + + if (cmp0096 == cmPolicies::OLD || cmp0096 == cmPolicies::WARN) { + char vb[MAX_VERSION_COMPONENTS][std::numeric_limits<unsigned>::digits10]; + unsigned v[MAX_VERSION_COMPONENTS] = { 0, 0, 0, 0 }; + const int vc = std::sscanf(version.c_str(), "%u.%u.%u.%u", &v[0], &v[1], + &v[2], &v[3]); + for (auto i = 0u; i < MAX_VERSION_COMPONENTS; ++i) { + if (int(i) < vc) { + std::sprintf(vb[i], "%u", v[i]); + version_string += &"."[std::size_t(i == 0)]; + version_string += vb[i]; + version_components[i] = vb[i]; + } else { + vb[i][0] = '\x00'; + } + } + } else { + // The regex above verified that we have a .-separated string of + // non-negative integer components. Keep the original string. + version_string = std::move(version); + // Split the integer components. + auto components = cmSystemTools::SplitString(version_string, '.'); + for (auto i = 0u; i < components.size(); ++i) { + version_components[i] = std::move(components[i]); } } std::string vv; vv = projectName + "_VERSION"; - this->Makefile->AddDefinition("PROJECT_VERSION", vs.c_str()); - this->Makefile->AddDefinition(vv, vs.c_str()); + this->Makefile->AddDefinition("PROJECT_VERSION", version_string); + this->Makefile->AddDefinition(vv, version_string); vv = projectName + "_VERSION_MAJOR"; - this->Makefile->AddDefinition("PROJECT_VERSION_MAJOR", vb[0]); - this->Makefile->AddDefinition(vv, vb[0]); + this->Makefile->AddDefinition("PROJECT_VERSION_MAJOR", + version_components[0]); + this->Makefile->AddDefinition(vv, version_components[0]); vv = projectName + "_VERSION_MINOR"; - this->Makefile->AddDefinition("PROJECT_VERSION_MINOR", vb[1]); - this->Makefile->AddDefinition(vv, vb[1]); + this->Makefile->AddDefinition("PROJECT_VERSION_MINOR", + version_components[1]); + this->Makefile->AddDefinition(vv, version_components[1]); vv = projectName + "_VERSION_PATCH"; - this->Makefile->AddDefinition("PROJECT_VERSION_PATCH", vb[2]); - this->Makefile->AddDefinition(vv, vb[2]); + this->Makefile->AddDefinition("PROJECT_VERSION_PATCH", + version_components[2]); + this->Makefile->AddDefinition(vv, version_components[2]); vv = projectName + "_VERSION_TWEAK"; - this->Makefile->AddDefinition("PROJECT_VERSION_TWEAK", vb[3]); - this->Makefile->AddDefinition(vv, vb[3]); + this->Makefile->AddDefinition("PROJECT_VERSION_TWEAK", + version_components[3]); + this->Makefile->AddDefinition(vv, version_components[3]); // Also, try set top level variables - TopLevelCMakeVarCondSet("CMAKE_PROJECT_VERSION", vs.c_str()); - TopLevelCMakeVarCondSet("CMAKE_PROJECT_VERSION_MAJOR", vb[0]); - TopLevelCMakeVarCondSet("CMAKE_PROJECT_VERSION_MINOR", vb[1]); - TopLevelCMakeVarCondSet("CMAKE_PROJECT_VERSION_PATCH", vb[2]); - TopLevelCMakeVarCondSet("CMAKE_PROJECT_VERSION_TWEAK", vb[3]); + TopLevelCMakeVarCondSet("CMAKE_PROJECT_VERSION", version_string.c_str()); + TopLevelCMakeVarCondSet("CMAKE_PROJECT_VERSION_MAJOR", + version_components[0].c_str()); + TopLevelCMakeVarCondSet("CMAKE_PROJECT_VERSION_MINOR", + version_components[1].c_str()); + TopLevelCMakeVarCondSet("CMAKE_PROJECT_VERSION_PATCH", + version_components[2].c_str()); + TopLevelCMakeVarCondSet("CMAKE_PROJECT_VERSION_TWEAK", + version_components[3].c_str()); } else if (cmp0048 != cmPolicies::OLD) { // Set project VERSION variables to empty - std::vector<std::string> vv; - vv.emplace_back("PROJECT_VERSION"); - vv.emplace_back("PROJECT_VERSION_MAJOR"); - vv.emplace_back("PROJECT_VERSION_MINOR"); - vv.emplace_back("PROJECT_VERSION_PATCH"); - vv.emplace_back("PROJECT_VERSION_TWEAK"); - vv.push_back(projectName + "_VERSION"); - vv.push_back(projectName + "_VERSION_MAJOR"); - vv.push_back(projectName + "_VERSION_MINOR"); - vv.push_back(projectName + "_VERSION_PATCH"); - vv.push_back(projectName + "_VERSION_TWEAK"); + std::vector<std::string> vv = { "PROJECT_VERSION", + "PROJECT_VERSION_MAJOR", + "PROJECT_VERSION_MINOR", + "PROJECT_VERSION_PATCH", + "PROJECT_VERSION_TWEAK", + projectName + "_VERSION", + projectName + "_VERSION_MAJOR", + projectName + "_VERSION_MINOR", + projectName + "_VERSION_PATCH", + projectName + "_VERSION_TWEAK" }; if (this->Makefile->IsRootMakefile()) { vv.emplace_back("CMAKE_PROJECT_VERSION"); vv.emplace_back("CMAKE_PROJECT_VERSION_MAJOR"); @@ -287,7 +306,7 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args, } std::string vw; for (std::string const& i : vv) { - const char* v = this->Makefile->GetDefinition(i); + const char* const v = this->Makefile->GetDefinition(i); if (v && *v) { if (cmp0048 == cmPolicies::WARN) { if (!injectedProjectCommand) { @@ -307,20 +326,17 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args, } } - this->Makefile->AddDefinition("PROJECT_DESCRIPTION", description.c_str()); - this->Makefile->AddDefinition(projectName + "_DESCRIPTION", - description.c_str()); + this->Makefile->AddDefinition("PROJECT_DESCRIPTION", description); + this->Makefile->AddDefinition(projectName + "_DESCRIPTION", description); TopLevelCMakeVarCondSet("CMAKE_PROJECT_DESCRIPTION", description.c_str()); - this->Makefile->AddDefinition("PROJECT_HOMEPAGE_URL", homepage.c_str()); - this->Makefile->AddDefinition(projectName + "_HOMEPAGE_URL", - homepage.c_str()); + this->Makefile->AddDefinition("PROJECT_HOMEPAGE_URL", homepage); + this->Makefile->AddDefinition(projectName + "_HOMEPAGE_URL", homepage); TopLevelCMakeVarCondSet("CMAKE_PROJECT_HOMEPAGE_URL", homepage.c_str()); if (languages.empty()) { // if no language is specified do c and c++ - languages.emplace_back("C"); - languages.emplace_back("CXX"); + languages = { "C", "CXX" }; } this->Makefile->EnableLanguage(languages, false); @@ -337,7 +353,7 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args, bool cmProjectCommand::IncludeByVariable(const std::string& variable) { - const char* include = this->Makefile->GetDefinition(variable); + const char* const include = this->Makefile->GetDefinition(variable); if (!include) { return true; } @@ -351,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/cmProjectCommand.h b/Source/cmProjectCommand.h index f1d03e7..8b9bcc8 100644 --- a/Source/cmProjectCommand.h +++ b/Source/cmProjectCommand.h @@ -8,6 +8,8 @@ #include <string> #include <vector> +#include "cm_memory.hxx" + #include "cmCommand.h" class cmExecutionStatus; @@ -26,7 +28,10 @@ public: /** * This is a virtual constructor for the command. */ - cmCommand* Clone() override { return new cmProjectCommand; } + std::unique_ptr<cmCommand> Clone() override + { + return cm::make_unique<cmProjectCommand>(); + } /** * This is called when the command is first encountered in diff --git a/Source/cmProperty.cxx b/Source/cmProperty.cxx deleted file mode 100644 index 27f0ecd..0000000 --- a/Source/cmProperty.cxx +++ /dev/null @@ -1,26 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing for details. */ -#include "cmProperty.h" - -void cmProperty::Set(const char* value) -{ - this->Value = value; - this->ValueHasBeenSet = true; -} - -void cmProperty::Append(const char* value, bool asString) -{ - if (!this->Value.empty() && *value && !asString) { - this->Value += ";"; - } - this->Value += value; - this->ValueHasBeenSet = true; -} - -const char* cmProperty::GetValue() const -{ - if (this->ValueHasBeenSet) { - return this->Value.c_str(); - } - return nullptr; -} diff --git a/Source/cmProperty.h b/Source/cmProperty.h index d11c5ef..80f131a 100644 --- a/Source/cmProperty.h +++ b/Source/cmProperty.h @@ -5,8 +5,6 @@ #include "cmConfigure.h" // IWYU pragma: keep -#include <string> - class cmProperty { public: @@ -22,22 +20,6 @@ public: CACHED_VARIABLE, INSTALL }; - - // set this property - void Set(const char* value); - - // append to this property - void Append(const char* value, bool asString = false); - - // get the value - const char* GetValue() const; - - // construct with the value not set - cmProperty() { this->ValueHasBeenSet = false; } - -protected: - std::string Value; - bool ValueHasBeenSet; }; #endif diff --git a/Source/cmPropertyMap.cxx b/Source/cmPropertyMap.cxx index 3f6d7c8..3ed4c05 100644 --- a/Source/cmPropertyMap.cxx +++ b/Source/cmPropertyMap.cxx @@ -3,40 +3,21 @@ #include "cmPropertyMap.h" #include <algorithm> -#include <assert.h> #include <utility> -cmProperty* cmPropertyMap::GetOrCreateProperty(const std::string& name) +void cmPropertyMap::Clear() { - cmPropertyMap::iterator it = this->find(name); - cmProperty* prop; - if (it == this->end()) { - prop = &(*this)[name]; - } else { - prop = &(it->second); - } - return prop; -} - -std::vector<std::string> cmPropertyMap::GetPropertyList() const -{ - std::vector<std::string> keyList; - for (auto const& i : *this) { - keyList.push_back(i.first); - } - std::sort(keyList.begin(), keyList.end()); - return keyList; + Map_.clear(); } void cmPropertyMap::SetProperty(const std::string& name, const char* value) { if (!value) { - this->erase(name); + Map_.erase(name); return; } - cmProperty* prop = this->GetOrCreateProperty(name); - prop->Set(value); + Map_[name] = value; } void cmPropertyMap::AppendProperty(const std::string& name, const char* value, @@ -47,17 +28,53 @@ void cmPropertyMap::AppendProperty(const std::string& name, const char* value, return; } - cmProperty* prop = this->GetOrCreateProperty(name); - prop->Append(value, asString); + { + std::string& pVal = Map_[name]; + if (!pVal.empty() && !asString) { + pVal += ';'; + } + pVal += value; + } +} + +void cmPropertyMap::RemoveProperty(const std::string& name) +{ + Map_.erase(name); } const char* cmPropertyMap::GetPropertyValue(const std::string& name) const { - assert(!name.empty()); + { + auto it = Map_.find(name); + if (it != Map_.end()) { + return it->second.c_str(); + } + } + return nullptr; +} - cmPropertyMap::const_iterator it = this->find(name); - if (it == this->end()) { - return nullptr; +std::vector<std::string> cmPropertyMap::GetKeys() const +{ + std::vector<std::string> keyList; + keyList.reserve(Map_.size()); + for (auto const& item : Map_) { + keyList.push_back(item.first); + } + std::sort(keyList.begin(), keyList.end()); + return keyList; +} + +std::vector<std::pair<std::string, std::string>> cmPropertyMap::GetList() const +{ + typedef std::pair<std::string, std::string> StringPair; + std::vector<StringPair> kvList; + kvList.reserve(Map_.size()); + for (auto const& item : Map_) { + kvList.emplace_back(item.first, item.second); } - return it->second.GetValue(); + std::sort(kvList.begin(), kvList.end(), + [](StringPair const& a, StringPair const& b) { + return a.first < b.first; + }); + return kvList; } diff --git a/Source/cmPropertyMap.h b/Source/cmPropertyMap.h index 5a05150..9aed349 100644 --- a/Source/cmPropertyMap.h +++ b/Source/cmPropertyMap.h @@ -5,25 +5,47 @@ #include "cmConfigure.h" // IWYU pragma: keep -#include "cmProperty.h" - -#include <map> #include <string> +#include <unordered_map> +#include <utility> #include <vector> -class cmPropertyMap : public std::map<std::string, cmProperty> +/** \class cmPropertyMap + * \brief String property map. + */ +class cmPropertyMap { public: - cmProperty* GetOrCreateProperty(const std::string& name); + // -- General + + //! Clear property list + void Clear(); - std::vector<std::string> GetPropertyList() const; + // -- Properties + //! Set the property value void SetProperty(const std::string& name, const char* value); + //! Append to the property value void AppendProperty(const std::string& name, const char* value, bool asString = false); + //! Get the property value const char* GetPropertyValue(const std::string& name) const; + + //! Remove the property @a name from the map + void RemoveProperty(const std::string& name); + + // -- Lists + + //! Get a sorted list of property keys + std::vector<std::string> GetKeys() const; + + //! Get a sorted by key list of property key,value pairs + std::vector<std::pair<std::string, std::string>> GetList() const; + +private: + std::unordered_map<std::string, std::string> Map_; }; #endif diff --git a/Source/cmQTWrapCPPCommand.cxx b/Source/cmQTWrapCPPCommand.cxx index 9a764c6..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")); @@ -89,6 +88,6 @@ bool cmQTWrapCPPCommand::InitialPass(std::vector<std::string> const& args, } // Store the final list of source files. - this->Makefile->AddDefinition(sourceList, sourceListValue.c_str()); + this->Makefile->AddDefinition(sourceList, sourceListValue); return true; } diff --git a/Source/cmQTWrapCPPCommand.h b/Source/cmQTWrapCPPCommand.h index c1dcd54..88a2210 100644 --- a/Source/cmQTWrapCPPCommand.h +++ b/Source/cmQTWrapCPPCommand.h @@ -8,6 +8,8 @@ #include <string> #include <vector> +#include "cm_memory.hxx" + #include "cmCommand.h" class cmExecutionStatus; @@ -24,7 +26,10 @@ public: /** * This is a virtual constructor for the command. */ - cmCommand* Clone() override { return new cmQTWrapCPPCommand; } + std::unique_ptr<cmCommand> Clone() override + { + return cm::make_unique<cmQTWrapCPPCommand>(); + } /** * This is called when the command is first encountered in diff --git a/Source/cmQTWrapUICommand.cxx b/Source/cmQTWrapUICommand.cxx index 2223e2d..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; @@ -132,7 +127,7 @@ bool cmQTWrapUICommand::InitialPass(std::vector<std::string> const& args, } // Store the final list of source files and headers. - this->Makefile->AddDefinition(sourceList, sourceListValue.c_str()); - this->Makefile->AddDefinition(headerList, headerListValue.c_str()); + this->Makefile->AddDefinition(sourceList, sourceListValue); + this->Makefile->AddDefinition(headerList, headerListValue); return true; } diff --git a/Source/cmQTWrapUICommand.h b/Source/cmQTWrapUICommand.h index 15cab40..6a346d4 100644 --- a/Source/cmQTWrapUICommand.h +++ b/Source/cmQTWrapUICommand.h @@ -8,6 +8,8 @@ #include <string> #include <vector> +#include "cm_memory.hxx" + #include "cmCommand.h" class cmExecutionStatus; @@ -23,7 +25,10 @@ public: /** * This is a virtual constructor for the command. */ - cmCommand* Clone() override { return new cmQTWrapUICommand; } + std::unique_ptr<cmCommand> Clone() override + { + return cm::make_unique<cmQTWrapUICommand>(); + } /** * This is called when the command is first encountered in diff --git a/Source/cmQtAutoGen.cxx b/Source/cmQtAutoGen.cxx index 3683edd..9d29e5c 100644 --- a/Source/cmQtAutoGen.cxx +++ b/Source/cmQtAutoGen.cxx @@ -5,6 +5,7 @@ #include "cmAlgorithms.h" #include "cmDuration.h" #include "cmProcessOutput.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmsys/FStream.hxx" #include "cmsys/RegularExpression.hxx" @@ -52,9 +53,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)) { @@ -293,9 +292,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(); @@ -324,9 +322,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; } @@ -352,9 +349,8 @@ bool cmQtAutoGen::RccLister::list(std::string const& qrcFile, // Log command if (verbose) { - std::string msg = "Running command:\n"; - msg += QuotedCommand(cmd); - msg += '\n'; + std::string msg = + cmStrCat("Running command:\n", QuotedCommand(cmd), '\n'); cmSystemTools::Stdout(msg); } @@ -363,9 +359,8 @@ 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"; @@ -391,9 +386,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 9c52129..619fff1 100644 --- a/Source/cmQtAutoGen.h +++ b/Source/cmQtAutoGen.h @@ -5,7 +5,7 @@ #include "cmConfigure.h" // IWYU pragma: keep -#include <memory> // IWYU pragma: keep +#include <memory> #include <string> #include <vector> diff --git a/Source/cmQtAutoGenGlobalInitializer.cxx b/Source/cmQtAutoGenGlobalInitializer.cxx index ef8a56b..abc69d0 100644 --- a/Source/cmQtAutoGenGlobalInitializer.cxx +++ b/Source/cmQtAutoGenGlobalInitializer.cxx @@ -1,10 +1,7 @@ /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmQtAutoGenGlobalInitializer.h" -#include "cmQtAutoGen.h" -#include "cmQtAutoGenInitializer.h" -#include "cmAlgorithms.h" #include "cmCustomCommandLines.h" #include "cmDuration.h" #include "cmGeneratorTarget.h" @@ -12,12 +9,16 @@ #include "cmMakefile.h" #include "cmMessageType.h" #include "cmProcessOutput.h" +#include "cmQtAutoGen.h" +#include "cmQtAutoGenInitializer.h" #include "cmState.h" #include "cmStateTypes.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmTarget.h" -#include <memory> +#include "cm_memory.hxx" + #include <utility> cmQtAutoGenGlobalInitializer::Keywords::Keywords() @@ -48,8 +49,7 @@ cmQtAutoGenGlobalInitializer::cmQtAutoGenGlobalInitializer( { cmMakefile* makefile = localGen->GetMakefile(); // Detect global autogen target name - if (cmSystemTools::IsOn( - makefile->GetSafeDefinition("CMAKE_GLOBAL_AUTOGEN_TARGET"))) { + if (cmIsOn(makefile->GetSafeDefinition("CMAKE_GLOBAL_AUTOGEN_TARGET"))) { std::string targetName = makefile->GetSafeDefinition("CMAKE_GLOBAL_AUTOGEN_TARGET_NAME"); if (targetName.empty()) { @@ -60,8 +60,7 @@ cmQtAutoGenGlobalInitializer::cmQtAutoGenGlobalInitializer( } // Detect global autorcc target name - if (cmSystemTools::IsOn( - makefile->GetSafeDefinition("CMAKE_GLOBAL_AUTORCC_TARGET"))) { + if (cmIsOn(makefile->GetSafeDefinition("CMAKE_GLOBAL_AUTORCC_TARGET"))) { std::string targetName = makefile->GetSafeDefinition("CMAKE_GLOBAL_AUTORCC_TARGET_NAME"); if (targetName.empty()) { @@ -119,23 +118,17 @@ cmQtAutoGenGlobalInitializer::cmQtAutoGenGlobalInitializer( bool const uicDisabled = (uic && !uicAvailable); bool const rccDisabled = (rcc && !rccAvailable); if (mocDisabled || uicDisabled || rccDisabled) { - std::string msg = "AUTOGEN: No valid Qt version found for target "; - msg += target->GetName(); - msg += ". "; - msg += cmQtAutoGen::Tools(mocDisabled, uicDisabled, rccDisabled); - msg += " disabled. Consider adding:\n"; - { - std::string version = (qtVersion.second == 0) - ? std::string("<QTVERSION>") - : std::to_string(qtVersion.second); - std::string comp = uicDisabled ? "Widgets" : "Core"; - msg += " find_package(Qt"; - msg += version; - msg += " COMPONENTS "; - msg += comp; - msg += ")\n"; - } - msg += "to your CMakeLists.txt file."; + cmAlphaNum version = (qtVersion.second == 0) + ? cmAlphaNum("<QTVERSION>") + : cmAlphaNum(qtVersion.second); + cmAlphaNum component = uicDisabled ? "Widgets" : "Core"; + + std::string const msg = cmStrCat( + "AUTOGEN: No valid Qt version found for target ", + target->GetName(), ". ", + cmQtAutoGen::Tools(mocDisabled, uicDisabled, rccDisabled), + " disabled. Consider adding:\n", " find_package(Qt", version, + " COMPONENTS ", component, ")\n", "to your CMakeLists.txt file."); target->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, msg); } if (mocIsValid || uicIsValid || rccIsValid) { @@ -218,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(); } @@ -238,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/cmQtAutoGenGlobalInitializer.h b/Source/cmQtAutoGenGlobalInitializer.h index d56153a..d7f4cc6 100644 --- a/Source/cmQtAutoGenGlobalInitializer.h +++ b/Source/cmQtAutoGenGlobalInitializer.h @@ -8,7 +8,7 @@ #include "cmQtAutoGen.h" #include <map> -#include <memory> // IWYU pragma: keep +#include <memory> #include <string> #include <unordered_map> #include <vector> diff --git a/Source/cmQtAutoGenInitializer.cxx b/Source/cmQtAutoGenInitializer.cxx index 9985f93..c355a5f 100644 --- a/Source/cmQtAutoGenInitializer.cxx +++ b/Source/cmQtAutoGenInitializer.cxx @@ -4,7 +4,6 @@ #include "cmQtAutoGen.h" #include "cmQtAutoGenGlobalInitializer.h" -#include "cmAlgorithms.h" #include "cmCustomCommand.h" #include "cmCustomCommandLines.h" #include "cmFilePathChecksum.h" @@ -23,6 +22,7 @@ #include "cmSourceGroup.h" #include "cmState.h" #include "cmStateTypes.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmTarget.h" #include "cmake.h" @@ -38,6 +38,8 @@ #include <utility> #include <vector> +#include "cm_memory.hxx" + static std::size_t GetParallelCPUCount() { static std::size_t count = 0; @@ -154,30 +156,27 @@ std::string cmQtAutoGenInitializer::InfoWriter::ListJoin(IT it_begin, return res; } -std::string cmQtAutoGenInitializer::InfoWriter::ConfigKey( - const char* key, std::string const& config) +inline std::string cmQtAutoGenInitializer::InfoWriter::ConfigKey( + cm::string_view key, std::string const& config) { - std::string ckey = key; - ckey += '_'; - ckey += config; - return ckey; + return cmStrCat(key, "_", config); } -void cmQtAutoGenInitializer::InfoWriter::Write(const char* key, +void cmQtAutoGenInitializer::InfoWriter::Write(cm::string_view key, std::string const& value) { Ofs_ << "set(" << key << " " << cmOutputConverter::EscapeForCMake(value) << ")\n"; }; -void cmQtAutoGenInitializer::InfoWriter::WriteUInt(const char* key, +void cmQtAutoGenInitializer::InfoWriter::WriteUInt(cm::string_view key, unsigned int value) { Ofs_ << "set(" << key << " " << value << ")\n"; }; template <class C> -void cmQtAutoGenInitializer::InfoWriter::WriteStrings(const char* key, +void cmQtAutoGenInitializer::InfoWriter::WriteStrings(cm::string_view key, C const& container) { Ofs_ << "set(" << key << " \"" @@ -185,31 +184,29 @@ void cmQtAutoGenInitializer::InfoWriter::WriteStrings(const char* key, } void cmQtAutoGenInitializer::InfoWriter::WriteConfig( - const char* key, std::map<std::string, std::string> const& map) + cm::string_view key, std::map<std::string, std::string> const& map) { for (auto const& item : map) { - Write(ConfigKey(key, item.first).c_str(), item.second); + Write(ConfigKey(key, item.first), item.second); } }; template <class C> void cmQtAutoGenInitializer::InfoWriter::WriteConfigStrings( - const char* key, std::map<std::string, C> const& map) + cm::string_view key, std::map<std::string, C> const& map) { for (auto const& item : map) { - WriteStrings(ConfigKey(key, item.first).c_str(), item.second); + WriteStrings(ConfigKey(key, item.first), item.second); } } void cmQtAutoGenInitializer::InfoWriter::WriteNestedLists( - const char* key, std::vector<std::vector<std::string>> const& lists) + cm::string_view key, std::vector<std::vector<std::string>> const& lists) { std::vector<std::string> seplist; - for (const std::vector<std::string>& list : lists) { - std::string blist = "{"; - blist += ListJoin(list.begin(), list.end()); - blist += "}"; - seplist.push_back(std::move(blist)); + seplist.reserve(lists.size()); + for (std::vector<std::string> const& list : lists) { + seplist.push_back(cmStrCat("{", ListJoin(list.begin(), list.end()), "}")); } Write(key, cmJoin(seplist, cmQtAutoGen::ListSep)); }; @@ -246,9 +243,9 @@ bool cmQtAutoGenInitializer::InitCustomTargets() this->Verbosity = makefile->GetSafeDefinition("CMAKE_AUTOGEN_VERBOSE"); if (!this->Verbosity.empty()) { unsigned long iVerb = 0; - if (!cmSystemTools::StringToULong(this->Verbosity.c_str(), &iVerb)) { + if (!cmStrToULong(this->Verbosity, &iVerb)) { // Non numeric verbosity - this->Verbosity = cmSystemTools::IsOn(this->Verbosity) ? "1" : "0"; + this->Verbosity = cmIsOn(this->Verbosity) ? "1" : "0"; } } @@ -296,21 +293,15 @@ bool cmQtAutoGenInitializer::InitCustomTargets() std::string(), makefile->GetCurrentBinaryDirectory()); // Info directory - this->Dir.Info = cbd; - this->Dir.Info += "/CMakeFiles"; - this->Dir.Info += '/'; - this->Dir.Info += this->Target->GetName(); - this->Dir.Info += "_autogen"; - this->Dir.Info += ".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 @@ -321,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>"; } @@ -330,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); } } } @@ -350,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 = @@ -364,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) { @@ -381,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); } @@ -394,8 +381,7 @@ bool cmQtAutoGenInitializer::InitCustomTargets() std::string const deps = this->Target->GetSafeProperty("AUTOGEN_TARGET_DEPENDS"); if (!deps.empty()) { - std::vector<std::string> extraDeps; - cmSystemTools::ExpandListArgument(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); @@ -410,13 +396,12 @@ bool cmQtAutoGenInitializer::InitCustomTargets() // CMAKE_AUTOMOC_RELAXED_MODE deprecation warning if (this->Moc.Enabled) { - if (cmSystemTools::IsOn( - 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."; + if (cmIsOn(makefile->GetDefinition("CMAKE_AUTOMOC_RELAXED_MODE"))) { + std::string msg = + 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."); makefile->IssueMessage(MessageType::AUTHOR_WARNING, msg); } } @@ -456,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") && @@ -546,7 +531,7 @@ bool cmQtAutoGenInitializer::InitUic() std::string const usp = this->Target->GetSafeProperty("AUTOUIC_SEARCH_PATHS"); if (!usp.empty()) { - cmSystemTools::ExpandListArgument(usp, this->Uic.SearchPaths); + cmExpandList(usp, this->Uic.SearchPaths); std::string const& srcDir = makefile->GetCurrentSourceDirectory(); for (std::string& path : this->Uic.SearchPaths) { path = cmSystemTools::CollapseFullPath(path, srcDir); @@ -620,6 +605,7 @@ bool cmQtAutoGenInitializer::InitRcc() bool cmQtAutoGenInitializer::InitScanFiles() { cmMakefile* makefile = this->Target->Target->GetMakefile(); + cmake const* cm = makefile->GetCMakeInstance(); auto const& kw = this->GlobalInitializer->kw(); auto makeMUFile = [this, &kw](cmSourceFile* sf, std::string const& fullPath, @@ -665,25 +651,21 @@ bool cmQtAutoGenInitializer::InitScanFiles() if (!pathError.empty() || fullPath.empty()) { continue; } - std::string const& ext = sf->GetExtension(); + std::string const& extLower = + cmSystemTools::LowerCase(sf->GetExtension()); // Register files that will be scanned by moc or uic if (this->MocOrUicEnabled()) { - switch (cmSystemTools::GetFileFormat(ext)) { - case cmSystemTools::HEADER_FILE_FORMAT: - addMUFile(makeMUFile(sf, fullPath, true), true); - break; - case cmSystemTools::CXX_FILE_FORMAT: - addMUFile(makeMUFile(sf, fullPath, true), false); - break; - default: - break; + if (cm->IsHeaderExtension(extLower)) { + addMUFile(makeMUFile(sf, fullPath, true), true); + } else if (cm->IsSourceExtension(extLower)) { + addMUFile(makeMUFile(sf, fullPath, true), false); } } // Register rcc enabled files if (this->Rcc.Enabled) { - if ((ext == kw.qrc) && !sf->GetPropertyAsBool(kw.SKIP_AUTOGEN) && + if ((extLower == kw.qrc) && !sf->GetPropertyAsBool(kw.SKIP_AUTOGEN) && !sf->GetPropertyAsBool(kw.SKIP_AUTORCC)) { // Register qrc file Qrc qrc; @@ -695,7 +677,7 @@ bool cmQtAutoGenInitializer::InitScanFiles() { std::string const opts = sf->GetSafeProperty(kw.AUTORCC_OPTIONS); if (!opts.empty()) { - cmSystemTools::ExpandListArgument(opts, qrc.Options); + cmExpandList(opts, qrc.Options); } } this->Rcc.Qrcs.push_back(std::move(qrc)); @@ -715,21 +697,20 @@ bool cmQtAutoGenInitializer::InitScanFiles() extraHeaders.reserve(this->AutogenTarget.Sources.size() * 2); // Header search suffixes and extensions std::array<std::string, 2> const suffixes{ { "", "_p" } }; - auto const& exts = makefile->GetCMakeInstance()->GetHeaderExtensions(); + auto const& exts = cm->GetHeaderExtensions(); // Scan through sources for (auto const& pair : this->AutogenTarget.Sources) { MUFile const& muf = *pair.second; if (muf.MocIt || muf.UicIt) { // Search for the default header file and a private header std::string const& srcPath = muf.SF->GetFullPath(); - std::string basePath = cmQtAutoGen::SubDirPrefix(srcPath); - basePath += cmSystemTools::GetFilenameWithoutLastExtension(srcPath); + std::string basePath = + cmStrCat(cmQtAutoGen::SubDirPrefix(srcPath), + cmSystemTools::GetFilenameWithoutLastExtension(srcPath)); for (auto const& suffix : suffixes) { std::string const suffixedPath = basePath + suffix; for (auto const& ext : exts) { - std::string fullPath = suffixedPath; - fullPath += '.'; - fullPath += ext; + std::string fullPath = cmStrCat(suffixedPath, '.', ext); auto constexpr locationKind = cmSourceFileLocationKind::Known; cmSourceFile* sf = makefile->GetSource(fullPath, locationKind); @@ -784,10 +765,10 @@ bool cmQtAutoGenInitializer::InitScanFiles() if (!pathError.empty() || fullPath.empty()) { continue; } - std::string const& ext = sf->GetExtension(); + std::string const& extLower = + cmSystemTools::LowerCase(sf->GetExtension()); - auto const fileFormat = cmSystemTools::GetFileFormat(ext); - if (fileFormat == cmSystemTools::HEADER_FILE_FORMAT) { + if (cm->IsHeaderExtension(extLower)) { if (this->AutogenTarget.Headers.find(sf) == this->AutogenTarget.Headers.end()) { auto muf = makeMUFile(sf, fullPath, false); @@ -795,7 +776,7 @@ bool cmQtAutoGenInitializer::InitScanFiles() this->AutogenTarget.Headers.emplace(sf, std::move(muf)); } } - } else if (fileFormat == cmSystemTools::CXX_FILE_FORMAT) { + } else if (cm->IsSourceExtension(extLower)) { if (this->AutogenTarget.Sources.find(sf) == this->AutogenTarget.Sources.end()) { auto muf = makeMUFile(sf, fullPath, false); @@ -803,7 +784,7 @@ bool cmQtAutoGenInitializer::InitScanFiles() this->AutogenTarget.Sources.emplace(sf, std::move(muf)); } } - } else if (this->Uic.Enabled && (ext == kw.ui)) { + } else if (this->Uic.Enabled && (extLower == kw.ui)) { // .ui file std::string realPath = cmSystemTools::GetRealPath(fullPath); bool const skipAutogen = sf->GetPropertyAsBool(kw.SKIP_AUTOGEN); @@ -814,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; - cmSystemTools::ExpandListArgument(uicOpts, optsVec); + std::vector<std::string> optsVec = cmExpandedList(uicOpts); this->Uic.FileOptions.push_back(std::move(optsVec)); } } else { @@ -834,9 +814,8 @@ bool cmQtAutoGenInitializer::InitScanFiles() this->AutogenTarget.DependFiles.insert(muf->RealPath); } } else if (this->CMP0071Warn) { - std::string msg; - msg += cmPolicies::GetPolicyWarning(cmPolicies::CMP0071); - msg += '\n'; + std::string msg = + cmStrCat(cmPolicies::GetPolicyWarning(cmPolicies::CMP0071), '\n'); std::string property; if (this->Moc.Enabled && this->Uic.Enabled) { property = kw.SKIP_AUTOGEN; @@ -869,9 +848,8 @@ bool cmQtAutoGenInitializer::InitScanFiles() if (!this->Rcc.Qrcs.empty()) { const bool modernQt = (this->QtVersion.Major >= 5); // Target rcc options - std::vector<std::string> optionsTarget; - cmSystemTools::ExpandListArgument( - 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) { @@ -889,30 +867,19 @@ 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"); { - std::string rccFile = this->Dir.Build + "/"; - rccFile += qrc.PathChecksum; - rccFile += "/qrc_"; - rccFile += qrc.QrcName; - rccFile += ".cpp"; - qrc.RccFile = std::move(rccFile); - } - { - std::string base = this->Dir.Info; - base += "/RCC"; - base += qrc.QrcName; + std::string base = cmStrCat(this->Dir.Info, "/RCC", qrc.QrcName); if (!qrc.Unique) { base += qrc.PathChecksum; } - qrc.LockFile = base; - qrc.LockFile += ".lock"; + qrc.LockFile = cmStrCat(base, ".lock"); - qrc.InfoFile = base; - qrc.InfoFile += "Info.cmake"; + qrc.InfoFile = cmStrCat(base, "Info.cmake"); - qrc.SettingsFile = base; - qrc.SettingsFile += "Settings.txt"; + qrc.SettingsFile = cmStrCat(base, "Settings.txt"); if (this->MultiConfig) { for (std::string const& cfg : this->ConfigsList) { @@ -933,8 +900,7 @@ bool cmQtAutoGenInitializer::InitScanFiles() // Replace '-' with '_'. The former is not valid for symbol names. std::replace(name.begin(), name.end(), '-', '_'); if (!qrc.Unique) { - name += "_"; - name += qrc.PathChecksum; + name += cmStrCat("_", qrc.PathChecksum); } std::vector<std::string> nameOpts; nameOpts.emplace_back("-name"); @@ -991,10 +957,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 @@ -1158,16 +1122,14 @@ bool cmQtAutoGenInitializer::InitRccTargets() currentLine.push_back("$<CONFIG>"); commandLines.push_back(std::move(currentLine)); } - std::string ccComment = "Automatic RCC for "; - ccComment += FileProjectRelativePath(makefile, qrc.QrcFile); + std::string ccComment = cmStrCat( + "Automatic RCC for ", FileProjectRelativePath(makefile, qrc.QrcFile)); if (qrc.Generated || this->Rcc.GlobalTarget) { // 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; @@ -1227,9 +1189,8 @@ bool cmQtAutoGenInitializer::SetupCustomTargets() { // Create info directory on demand if (!cmSystemTools::MakeDirectory(this->Dir.Info)) { - std::string emsg = ("AutoGen: Could not create directory: "); - emsg += Quoted(this->Dir.Info); - cmSystemTools::Error(emsg); + cmSystemTools::Error(cmStrCat("AutoGen: Could not create directory: ", + Quoted(this->Dir.Info))); return false; } @@ -1312,10 +1273,8 @@ bool cmQtAutoGenInitializer::SetupWriteAutogenInfo() } if (muf->MocIt || muf->UicIt) { headers.emplace_back(muf->RealPath); - std::string flags; - flags += muf->MocIt ? 'M' : 'm'; - flags += muf->UicIt ? 'U' : 'u'; - headersFlags.emplace_back(std::move(flags)); + headersFlags.emplace_back( + cmStrCat(muf->MocIt ? "M" : "m", muf->UicIt ? "U" : "u")); } } } @@ -1324,14 +1283,13 @@ bool cmQtAutoGenInitializer::SetupWriteAutogenInfo() cmFilePathChecksum const fpathCheckSum(makefile); std::unordered_set<std::string> emitted; for (std::string const& hdr : headers) { - std::string basePath = fpathCheckSum.getPart(hdr); - basePath += "/moc_"; - basePath += cmSystemTools::GetFilenameWithoutLastExtension(hdr); - for (unsigned int ii = 1; ii != 1024; ++ii) { + std::string basePath = + cmStrCat(fpathCheckSum.getPart(hdr), "/moc_", + cmSystemTools::GetFilenameWithoutLastExtension(hdr)); + for (int ii = 1; ii != 1024; ++ii) { std::string path = basePath; if (ii > 1) { - path += '_'; - path += std::to_string(ii); + path += cmStrCat("_", ii); } path += ".cpp"; if (emitted.emplace(path).second) { @@ -1370,10 +1328,8 @@ bool cmQtAutoGenInitializer::SetupWriteAutogenInfo() } if (muf->MocIt || muf->UicIt) { sources.emplace_back(muf->RealPath); - std::string flags; - flags += muf->MocIt ? 'M' : 'm'; - flags += muf->UicIt ? 'U' : 'u'; - sourcesFlags.emplace_back(std::move(flags)); + sourcesFlags.emplace_back( + cmStrCat(muf->MocIt ? "M" : "m", muf->UicIt ? "U" : "u")); } } } @@ -1427,9 +1383,8 @@ bool cmQtAutoGenInitializer::SetupWriteAutogenInfo() ofs.WriteStrings("AM_UIC_SEARCH_PATHS", this->Uic.SearchPaths); } } else { - std::string err = "AutoGen: Could not write file "; - err += this->AutogenTarget.InfoFile; - cmSystemTools::Error(err); + cmSystemTools::Error(cmStrCat("AutoGen: Could not write file ", + this->AutogenTarget.InfoFile)); return false; } @@ -1468,9 +1423,8 @@ bool cmQtAutoGenInitializer::SetupWriteRccInfo() ofs.WriteStrings("ARCC_OPTIONS", qrc.Options); ofs.WriteStrings("ARCC_INPUTS", qrc.Resources); } else { - std::string err = "AutoRcc: Could not write file "; - err += qrc.InfoFile; - cmSystemTools::Error(err); + cmSystemTools::Error( + cmStrCat("AutoRcc: Could not write file ", qrc.InfoFile)); return false; } } @@ -1525,13 +1479,10 @@ bool cmQtAutoGenInitializer::AddToSourceGroup(std::string const& fileName, if (!groupName.empty()) { sourceGroup = makefile->GetOrCreateSourceGroup(groupName); if (sourceGroup == nullptr) { - std::string err; - err += genNameUpper; - err += " error in "; - err += property; - err += ": Could not find or create the source group "; - err += cmQtAutoGen::Quoted(groupName); - cmSystemTools::Error(err); + cmSystemTools::Error( + cmStrCat(genNameUpper, " error in ", property, + ": Could not find or create the source group ", + cmQtAutoGen::Quoted(groupName))); return false; } } @@ -1551,7 +1502,7 @@ void cmQtAutoGenInitializer::AddCleanFile(std::string const& fileName) static unsigned int CharPtrToUInt(const char* const input) { unsigned long tmp = 0; - if (input != nullptr && cmSystemTools::StringToULong(input, &tmp)) { + if (input != nullptr && cmStrToULong(input, &tmp)) { return static_cast<unsigned int>(tmp); } return 0; @@ -1623,12 +1574,8 @@ bool cmQtAutoGenInitializer::GetQtExecutable(GenVarsT& genVars, bool ignoreMissingTarget) const { auto print_err = [this, &genVars](std::string const& err) { - std::string msg = genVars.GenNameUpper; - msg += " for target "; - msg += this->Target->GetName(); - msg += ": "; - msg += err; - cmSystemTools::Error(msg); + cmSystemTools::Error(cmStrCat(genVars.GenNameUpper, " for target ", + this->Target->GetName(), ": ", err)); }; // Custom executable @@ -1688,11 +1635,8 @@ bool cmQtAutoGenInitializer::GetQtExecutable(GenVarsT& genVars, std::make_shared<cmQtAutoGen::CompilerFeatures>(); return true; } - std::string err = "Could not find "; - err += executable; - err += " executable target "; - err += targetName; - print_err(err); + print_err(cmStrCat("Could not find ", executable, " executable target ", + targetName)); return false; } } diff --git a/Source/cmQtAutoGenInitializer.h b/Source/cmQtAutoGenInitializer.h index aa073d1..7d72cad 100644 --- a/Source/cmQtAutoGenInitializer.h +++ b/Source/cmQtAutoGenInitializer.h @@ -6,9 +6,10 @@ #include "cmConfigure.h" // IWYU pragma: keep #include "cmGeneratedFileStream.h" #include "cmQtAutoGen.h" +#include "cm_string_view.hxx" #include <map> -#include <memory> // IWYU pragma: keep +#include <memory> #include <ostream> #include <set> #include <string> @@ -85,24 +86,24 @@ public: /// @return True if the file is open explicit operator bool() const { return static_cast<bool>(Ofs_); } - void Write(const char* text) { Ofs_ << text; } - void Write(const char* key, std::string const& value); - void WriteUInt(const char* key, unsigned int value); + void Write(cm::string_view text) { Ofs_ << text; } + void Write(cm::string_view, std::string const& value); + void WriteUInt(cm::string_view, unsigned int value); template <class C> - void WriteStrings(const char* key, C const& container); - void WriteConfig(const char* key, + void WriteStrings(cm::string_view, C const& container); + void WriteConfig(cm::string_view, std::map<std::string, std::string> const& map); template <class C> - void WriteConfigStrings(const char* key, + void WriteConfigStrings(cm::string_view, std::map<std::string, C> const& map); - void WriteNestedLists(const char* key, + void WriteNestedLists(cm::string_view, std::vector<std::vector<std::string>> const& lists); private: template <class IT> static std::string ListJoin(IT it_begin, IT it_end); - static std::string ConfigKey(const char* key, std::string const& config); + static std::string ConfigKey(cm::string_view, std::string const& config); private: cmGeneratedFileStream Ofs_; diff --git a/Source/cmQtAutoGenerator.cxx b/Source/cmQtAutoGenerator.cxx index e1c435b..90361a9 100644 --- a/Source/cmQtAutoGenerator.cxx +++ b/Source/cmQtAutoGenerator.cxx @@ -1,16 +1,17 @@ /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmQtAutoGenerator.h" -#include "cmQtAutoGen.h" +#include "cm_memory.hxx" #include "cmsys/FStream.hxx" -#include "cmAlgorithms.h" #include "cmGlobalGenerator.h" #include "cmMakefile.h" +#include "cmQtAutoGen.h" #include "cmState.h" #include "cmStateDirectory.h" #include "cmStateSnapshot.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmake.h" @@ -21,11 +22,11 @@ cmQtAutoGenerator::Logger::Logger() std::string verbose; if (cmSystemTools::GetEnv("VERBOSE", verbose) && !verbose.empty()) { unsigned long iVerbose = 0; - if (cmSystemTools::StringToULong(verbose.c_str(), &iVerbose)) { + if (cmStrToULong(verbose, &iVerbose)) { SetVerbosity(static_cast<unsigned int>(iVerbose)); } else { // Non numeric verbosity - SetVerbose(cmSystemTools::IsOn(verbose)); + SetVerbose(cmIsOn(verbose)); } } } @@ -33,7 +34,7 @@ cmQtAutoGenerator::Logger::Logger() std::string colorEnv; cmSystemTools::GetEnv("COLOR", colorEnv); if (!colorEnv.empty()) { - SetColorOutput(cmSystemTools::IsOn(colorEnv)); + SetColorOutput(cmIsOn(colorEnv)); } else { SetColorOutput(true); } @@ -45,7 +46,7 @@ cmQtAutoGenerator::Logger::~Logger() = default; void cmQtAutoGenerator::Logger::RaiseVerbosity(std::string const& value) { unsigned long verbosity = 0; - if (cmSystemTools::StringToULong(value.c_str(), &verbosity)) { + if (cmStrToULong(value, &verbosity)) { if (this->Verbosity_ < verbosity) { this->Verbosity_ = static_cast<unsigned int>(verbosity); } @@ -59,19 +60,13 @@ void cmQtAutoGenerator::Logger::SetColorOutput(bool value) std::string cmQtAutoGenerator::Logger::HeadLine(std::string const& title) { - std::string head = title; - head += '\n'; - head.append(head.size() - 1, '-'); - head += '\n'; - return head; + return cmStrCat(title, "\n", std::string(title.size(), '-'), "\n"); } void cmQtAutoGenerator::Logger::Info(GenT genType, std::string const& message) const { - std::string msg = GeneratorName(genType); - msg += ": "; - msg += message; + std::string msg = cmStrCat(GeneratorName(genType), ": ", message); if (msg.back() != '\n') { msg.push_back('\n'); } @@ -109,19 +104,13 @@ void cmQtAutoGenerator::Logger::WarningFile(GenT genType, std::string const& filename, std::string const& message) const { - std::string msg = " "; - msg += Quoted(filename); - msg.push_back('\n'); - // Message - msg += message; - Warning(genType, msg); + Warning(genType, cmStrCat(" ", Quoted(filename), "\n", message)); } void cmQtAutoGenerator::Logger::Error(GenT genType, std::string const& message) const { - std::string msg; - msg += HeadLine(GeneratorName(genType) + " error"); + std::string msg = HeadLine(GeneratorName(genType) + " error"); // Message msg += message; if (msg.back() != '\n') { @@ -138,12 +127,7 @@ void cmQtAutoGenerator::Logger::ErrorFile(GenT genType, std::string const& filename, std::string const& message) const { - std::string emsg = " "; - emsg += Quoted(filename); - emsg += '\n'; - // Message - emsg += message; - Error(genType, emsg); + Error(genType, cmStrCat(" ", Quoted(filename), '\n', message)); } void cmQtAutoGenerator::Logger::ErrorCommand( @@ -279,10 +263,8 @@ bool cmQtAutoGenerator::Run(std::string const& infoFile, InfoFile_ = infoFile; cmSystemTools::ConvertToUnixSlashes(InfoFile_); if (!InfoFileTime_.Load(InfoFile_)) { - std::string msg = "AutoGen: The info file "; - msg += Quoted(InfoFile_); - msg += " is not readable\n"; - cmSystemTools::Stderr(msg); + cmSystemTools::Stderr(cmStrCat("AutoGen: The info file ", + Quoted(InfoFile_), " is not readable\n")); return false; } InfoDir_ = cmSystemTools::GetFilenamePath(infoFile); @@ -316,8 +298,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/cmQtAutoMocUic.cxx b/Source/cmQtAutoMocUic.cxx index 889f47d..df190a1 100644 --- a/Source/cmQtAutoMocUic.cxx +++ b/Source/cmQtAutoMocUic.cxx @@ -5,16 +5,18 @@ #include <algorithm> #include <array> #include <list> -#include <memory> #include <set> #include <sstream> #include <utility> +#include "cm_memory.hxx" + #include "cmAlgorithms.h" #include "cmCryptoHash.h" #include "cmGeneratedFileStream.h" #include "cmMakefile.h" #include "cmQtAutoGen.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmake.h" #include "cmsys/FStream.hxx" @@ -300,10 +302,9 @@ void cmQtAutoMocUic::JobMocPredefsT::Process() } // Execute command if (!RunProcess(GenT::MOC, result, cmd, reason.get())) { - std::string msg = "The content generation command for "; - msg += Quoted(predefsFileRel); - msg += " failed.\n"; - msg += result.ErrorMessage; + std::string msg = + cmStrCat("The content generation command for ", + Quoted(predefsFileRel), " failed.\n", result.ErrorMessage); LogCommandError(GenT::MOC, msg, cmd, result.StdOut); return; } @@ -312,9 +313,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 = "Writing "; - msg += Quoted(predefsFileRel); - msg += " failed."; + std::string msg = + cmStrCat("Writing ", Quoted(predefsFileRel), " failed."); LogFileError(GenT::MOC, predefsFileAbs, msg); return; } @@ -324,9 +324,8 @@ void cmQtAutoMocUic::JobMocPredefsT::Process() Log().Info(GenT::MOC, "Touching " + Quoted(predefsFileRel)); } if (!cmSystemTools::Touch(predefsFileAbs, false)) { - std::string msg = "Touching "; - msg += Quoted(predefsFileAbs); - msg += " failed."; + std::string msg = + cmStrCat("Touching ", Quoted(predefsFileAbs), " failed."); LogFileError(GenT::MOC, predefsFileAbs, msg); return; } @@ -345,9 +344,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; } @@ -355,9 +353,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; } @@ -369,11 +366,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; } @@ -661,13 +655,11 @@ bool cmQtAutoMocUic::JobEvaluateT::MocEvalSource( if (!sourceIncludesDotMoc && !parseData.Macro.empty() && !(relaxedMode && sourceIncludesMocUnderscore)) { { - std::string emsg = "The file contains a "; - emsg += Quoted(parseData.Macro); - emsg += " macro, but does not include "; - emsg += Quoted(sourceBase + ".moc"); - emsg += "!\nConsider to\n - add #include \""; - emsg += sourceBase; - emsg += ".moc\"\n - enable SKIP_AUTOMOC for this file"; + 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); } return false; @@ -679,11 +671,11 @@ bool cmQtAutoMocUic::JobEvaluateT::MocEvalSource( 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); + std::string msg = + cmStrCat("The file includes the moc file ", Quoted(incKey.Key), + ",\nbut the header could not be found " + "in the following locations\n", + MocMessageTestHeaders(headerBase)); LogFileError(GenT::MOC, sourceFile.FileName, msg); } return false; @@ -698,18 +690,14 @@ bool cmQtAutoMocUic::JobEvaluateT::MocEvalSource( // used. This is for KDE4 compatibility. { // Issue a warning - std::string msg = "The file contains a "; - msg += Quoted(parseData.Macro); - msg += " macro, but does not include "; - msg += Quoted(sourceBase + ".moc"); - msg += ".\nInstead it includes "; - msg += Quoted(incKey.Key); - msg += ".\nRunning moc on the source\n "; - msg += Quoted(sourceFile.FileName); - msg += "!\nBetter include "; - msg += Quoted(sourceBase + ".moc"); - msg += " for compatibility with regular mode.\n"; - msg += "This is a CMAKE_AUTOMOC_RELAXED_MODE warning.\n"; + 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); } // Create mapping @@ -747,12 +735,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 += ",\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); + std::string msg = + 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)); LogFileError(GenT::MOC, sourceFile.FileName, msg); return false; } @@ -762,28 +750,22 @@ bool cmQtAutoMocUic::JobEvaluateT::MocEvalSource( } // Issue a warning if (ownMoc && parseData.Macro.empty()) { - std::string msg = "The file includes the moc file "; - msg += Quoted(incKey.Key); - msg += ", but does not contain a\n"; - msg += MocConst().MacrosString(); - msg += " macro.\nRunning moc on the header\n "; - msg += Quoted(header->FileName); - msg += "!\nBetter include "; - msg += Quoted("moc_" + incKey.Base + ".cpp"); - msg += " for a compatibility with regular mode.\n"; - msg += "This is a CMAKE_AUTOMOC_RELAXED_MODE warning.\n"; + 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); } else { - std::string msg = "The file includes the moc file "; - msg += Quoted(incKey.Key); - msg += " instead of "; - msg += Quoted("moc_" + incKey.Base + ".cpp"); - msg += ".\nRunning moc on the header\n "; - msg += Quoted(header->FileName); - msg += "!\nBetter include "; - msg += Quoted("moc_" + incKey.Base + ".cpp"); - msg += " for compatibility with regular mode.\n"; - msg += "This is a CMAKE_AUTOMOC_RELAXED_MODE warning.\n"; + 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); } // Create mapping @@ -798,22 +780,19 @@ 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."; + std::string msg = 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."); LogFileError(GenT::MOC, sourceFile.FileName, msg); return false; } // Accept but issue a warning if moc isn't required if (parseData.Macro.empty()) { - std::string msg = "The file includes the moc file "; - msg += Quoted(incKey.Key); - msg += ", but does not contain a "; - msg += MocConst().MacrosString(); - msg += " macro."; + 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); } // Create mapping @@ -839,9 +818,7 @@ cmQtAutoMocUic::JobEvaluateT::MocFindIncludedHeader( } // Search in include directories for (std::string const& path : MocConst().IncludePaths) { - std::string testPath = path; - testPath += '/'; - testPath += includeBase; + std::string testPath = cmStrCat(path, '/', includeBase); SourceFileHandleT res = MocFindHeader(testPath); if (res) { return res; @@ -891,10 +868,9 @@ std::string cmQtAutoMocUic::JobEvaluateT::MocMessageTestHeaders( { std::ostringstream res; { - std::string exts = ".{"; - exts += cmJoin(BaseConst().HeaderExtensions, ","); - exts += '}'; - // Compose result string + 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'; @@ -912,9 +888,8 @@ 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 = "The source files\n "; - msg += Quoted(includerFileHandle->FileName); - msg += '\n'; + std::string msg = cmStrCat("The source files\n ", + Quoted(includerFileHandle->FileName), '\n'); for (auto const& item : handle->IncluderFiles) { msg += " "; msg += Quoted(item->FileName); @@ -1018,9 +993,8 @@ 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 = "The source files\n "; - msg += Quoted(includerFileHandle->FileName); - msg += '\n'; + std::string msg = cmStrCat("The source files\n ", + Quoted(includerFileHandle->FileName), '\n'); for (auto const& item : handle->IncluderFiles) { msg += " "; msg += Quoted(item->FileName); @@ -1061,8 +1035,7 @@ cmQtAutoMocUic::JobEvaluateT::UicFindIncludedUi( std::string const& sourceFile, std::string const& sourceDir, IncludeKeyT const& incKey) const { - std::string searchFileName = incKey.Base; - searchFileName += ".ui"; + std::string searchFileName = cmStrCat(incKey.Base, ".ui"); // Collect search paths list std::vector<std::string> testFiles; { @@ -1072,26 +1045,17 @@ cmQtAutoMocUic::JobEvaluateT::UicFindIncludedUi( // Vicinity of the source testFiles.emplace_back(sourceDir + searchFileName); if (!incKey.Dir.empty()) { - std::string path = sourceDir; - path += incKey.Dir; - path += searchFileName; - testFiles.emplace_back(path); + testFiles.emplace_back(cmStrCat(sourceDir, incKey.Dir, searchFileName)); } // AUTOUIC search paths if (!searchPaths.empty()) { for (std::string const& sPath : searchPaths) { - std::string path = sPath; - path += '/'; - path += searchFileName; - testFiles.emplace_back(std::move(path)); + testFiles.emplace_back(cmStrCat(sPath, '/', searchFileName)); } if (!incKey.Dir.empty()) { for (std::string const& sPath : searchPaths) { - std::string path = sPath; - path += '/'; - path += incKey.Dir; - path += searchFileName; - testFiles.emplace_back(std::move(path)); + testFiles.emplace_back( + cmStrCat(sPath, '/', incKey.Dir, searchFileName)); } } } @@ -1116,11 +1080,10 @@ cmQtAutoMocUic::JobEvaluateT::UicFindIncludedUi( // Log error { - std::string msg = "The file includes the uic file "; - msg += Quoted(incKey.Key); - msg += ",\nbut the user interface file "; - msg += Quoted(searchFileName); - msg += "\ncould not be found in the following locations\n"; + 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"); for (std::string const& testFile : testFiles) { msg += " "; msg += Quoted(testFile); @@ -1203,10 +1166,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; } @@ -1214,10 +1176,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; } @@ -1225,10 +1186,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; } @@ -1237,12 +1197,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; } @@ -1251,10 +1208,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; } @@ -1274,12 +1230,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; } @@ -1344,10 +1298,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; } @@ -1355,10 +1308,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; } @@ -1366,10 +1318,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; } @@ -1377,10 +1328,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; } @@ -1416,10 +1366,9 @@ void cmQtAutoMocUic::JobMocT::Process() } } else { // Moc command failed - std::string msg = "The moc process failed to compile\n "; - msg += Quoted(sourceFile); - msg += "\ninto\n "; - msg += Quoted(outputFile); + std::string msg = + cmStrCat("The moc process failed to compile\n ", Quoted(sourceFile), + "\ninto\n ", Quoted(outputFile)); if (Mapping->IncluderFiles.empty()) { msg += ".\n"; } else { @@ -1465,11 +1414,9 @@ void cmQtAutoMocUic::JobUicT::Process() } } else { // Uic command failed - std::string msg = "The uic process failed to compile\n "; - msg += Quoted(sourceFile); - msg += "\ninto\n "; - msg += Quoted(outputFile); - msg += "\nincluded by\n"; + std::string msg = + cmStrCat("The uic process failed to compile\n ", Quoted(sourceFile), + "\ninto\n ", Quoted(outputFile), "\nincluded by\n"); for (auto const& item : Mapping->IncluderFiles) { msg += " "; msg += Quoted(item->FileName); @@ -1544,8 +1491,8 @@ bool cmQtAutoMocUic::Init(cmMakefile* makefile) return makefile->IsOn(key); }; auto InfoGetList = [makefile](const char* key) -> std::vector<std::string> { - std::vector<std::string> list; - cmSystemTools::ExpandListArgument(makefile->GetSafeDefinition(key), list); + std::vector<std::string> list = + cmExpandedList(makefile->GetSafeDefinition(key)); return list; }; auto InfoGetLists = @@ -1562,12 +1509,7 @@ bool cmQtAutoMocUic::Init(cmMakefile* makefile) if (length >= 2) { std::string::const_iterator itBeg = value.begin() + (pos + 1); std::string::const_iterator itEnd = itBeg + (length - 2); - { - std::string subValue(itBeg, itEnd); - std::vector<std::string> list; - cmSystemTools::ExpandListArgument(subValue, list); - lists.push_back(std::move(list)); - } + lists.emplace_back(cmExpandedList(std::string(itBeg, itEnd))); } pos += length; pos += ListSep.size(); @@ -1578,9 +1520,7 @@ bool cmQtAutoMocUic::Init(cmMakefile* makefile) auto InfoGetConfig = [makefile, this](const char* key) -> std::string { const char* valueConf = nullptr; { - std::string keyConf = key; - keyConf += '_'; - keyConf += InfoConfig(); + std::string keyConf = cmStrCat(key, '_', InfoConfig()); valueConf = makefile->GetDefinition(keyConf); } if (valueConf == nullptr) { @@ -1590,8 +1530,7 @@ bool cmQtAutoMocUic::Init(cmMakefile* makefile) }; auto InfoGetConfigList = [&InfoGetConfig](const char* key) -> std::vector<std::string> { - std::vector<std::string> list; - cmSystemTools::ExpandListArgument(InfoGetConfig(key), list); + std::vector<std::string> list = cmExpandedList(InfoGetConfig(key)); return list; }; auto LogInfoError = [this](std::string const& msg) -> bool { @@ -1622,7 +1561,7 @@ bool cmQtAutoMocUic::Init(cmMakefile* makefile) BaseConst_.MultiConfig = InfoGetBool("AM_MULTI_CONFIG"); { unsigned long num = 1; - if (cmSystemTools::StringToULong(InfoGet("AM_PARALLEL").c_str(), &num)) { + if (cmStrToULong(InfoGet("AM_PARALLEL"), &num)) { num = std::max<unsigned long>(num, 1); num = std::min<unsigned long>(num, ParallelMax); } @@ -1651,9 +1590,9 @@ bool cmQtAutoMocUic::Init(cmMakefile* makefile) return LogInfoError("CMake executable file name missing."); } if (!BaseConst_.CMakeExecutableTime.Load(BaseConst_.CMakeExecutable)) { - std::string error = "The CMake executable "; - error += Quoted(BaseConst_.CMakeExecutable); - error += " does not exist."; + std::string error = + cmStrCat("The CMake executable ", Quoted(BaseConst_.CMakeExecutable), + " does not exist."); return LogInfoError(error); } BaseConst_.ParseCacheFile = InfoGetConfig("AM_PARSE_CACHE_FILE"); @@ -1670,8 +1609,7 @@ bool cmQtAutoMocUic::Init(cmMakefile* makefile) // - Qt environment { unsigned long qtv = BaseConst_.QtVersionMajor; - if (cmSystemTools::StringToULong(InfoGet("AM_QT_VERSION_MAJOR").c_str(), - &qtv)) { + if (cmStrToULong(InfoGet("AM_QT_VERSION_MAJOR"), &qtv)) { BaseConst_.QtVersionMajor = static_cast<unsigned int>(qtv); } } @@ -1682,9 +1620,9 @@ bool cmQtAutoMocUic::Init(cmMakefile* makefile) MocConst_.Enabled = true; // Load the executable file time if (!MocConst_.ExecutableTime.Load(MocConst_.Executable)) { - std::string error = "The moc executable "; - error += Quoted(MocConst_.Executable); - error += " does not exist."; + std::string error = + cmStrCat("The moc executable ", Quoted(MocConst_.Executable), + " does not exist."); return LogInfoError(error); } for (std::string& sfl : InfoGetList("AM_MOC_SKIP")) { @@ -1750,9 +1688,9 @@ bool cmQtAutoMocUic::Init(cmMakefile* makefile) UicConst_.Enabled = true; // Load the executable file time if (!UicConst_.ExecutableTime.Load(UicConst_.Executable)) { - std::string error = "The uic executable "; - error += Quoted(UicConst_.Executable); - error += " does not exist."; + std::string error = + cmStrCat("The uic executable ", Quoted(UicConst_.Executable), + " does not exist."); return LogInfoError(error); } for (std::string& sfl : InfoGetList("AM_UIC_SKIP")) { @@ -1804,7 +1742,8 @@ bool cmQtAutoMocUic::Init(cmMakefile* makefile) // Headers { // Get file lists - const char *keyFiles = "AM_HEADERS", *keyFlags = "AM_HEADERS_FLAGS"; + const char* keyFiles = "AM_HEADERS"; + const char* keyFlags = "AM_HEADERS_FLAGS"; std::vector<std::string> files = InfoGetList(keyFiles); std::vector<std::string> flags = InfoGetList(keyFlags); std::vector<std::string> builds; @@ -1839,7 +1778,8 @@ bool cmQtAutoMocUic::Init(cmMakefile* makefile) // Sources { - const char *keyFiles = "AM_SOURCES", *keyFlags = "AM_SOURCES_FLAGS"; + const char* keyFiles = "AM_SOURCES"; + const char* 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())) { @@ -1892,7 +1832,7 @@ bool cmQtAutoMocUic::Init(cmMakefile* makefile) std::list<std::string>::iterator it = includes.begin(); while (it != includes.end()) { std::string const& path = *it; - if (cmSystemTools::StringStartsWith(path, ppath->c_str())) { + if (cmHasPrefix(path, *ppath)) { MocConst_.IncludePaths.push_back(path); it = includes.erase(it); } else { diff --git a/Source/cmQtAutoMocUic.h b/Source/cmQtAutoMocUic.h index 8061c13..dc18328 100644 --- a/Source/cmQtAutoMocUic.h +++ b/Source/cmQtAutoMocUic.h @@ -14,7 +14,7 @@ #include <atomic> #include <cstddef> #include <map> -#include <memory> // IWYU pragma: keep +#include <memory> #include <set> #include <string> #include <unordered_map> diff --git a/Source/cmQtAutoRcc.cxx b/Source/cmQtAutoRcc.cxx index 20885df..cc1a290 100644 --- a/Source/cmQtAutoRcc.cxx +++ b/Source/cmQtAutoRcc.cxx @@ -11,6 +11,7 @@ #include "cmFileLockResult.h" #include "cmMakefile.h" #include "cmProcessOutput.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" // -- Class methods @@ -27,17 +28,15 @@ bool cmQtAutoRcc::Init(cmMakefile* makefile) }; auto InfoGetList = [makefile](std::string const& key) -> std::vector<std::string> { - std::vector<std::string> list; - cmSystemTools::ExpandListArgument(makefile->GetSafeDefinition(key), list); + std::vector<std::string> list = + cmExpandedList(makefile->GetSafeDefinition(key)); return list; }; auto InfoGetConfig = [makefile, this](std::string const& key) -> std::string { const char* valueConf = nullptr; { - std::string keyConf = key; - keyConf += '_'; - keyConf += InfoConfig(); + std::string keyConf = cmStrCat(key, '_', InfoConfig()); valueConf = makefile->GetDefinition(keyConf); } if (valueConf == nullptr) { @@ -47,8 +46,7 @@ bool cmQtAutoRcc::Init(cmMakefile* makefile) }; auto InfoGetConfigList = [&InfoGetConfig](std::string const& key) -> std::vector<std::string> { - std::vector<std::string> list; - cmSystemTools::ExpandListArgument(InfoGetConfig(key), list); + std::vector<std::string> list = cmExpandedList(InfoGetConfig(key)); return list; }; auto LogInfoError = [this](std::string const& msg) -> bool { @@ -81,9 +79,8 @@ bool cmQtAutoRcc::Init(cmMakefile* makefile) // - Rcc executable RccExecutable_ = InfoGet("ARCC_RCC_EXECUTABLE"); if (!RccExecutableTime_.Load(RccExecutable_)) { - std::string error = "The rcc executable "; - error += Quoted(RccExecutable_); - error += " does not exist."; + std::string error = cmStrCat("The rcc executable ", Quoted(RccExecutable_), + " does not exist."); return LogInfoError(error); } RccListOptions_ = InfoGetList("ARCC_RCC_LIST_OPTIONS"); @@ -124,17 +121,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_; } @@ -178,10 +170,8 @@ bool cmQtAutoRcc::Process() std::string cmQtAutoRcc::MultiConfigOutput() const { static std::string const suffix = "_CMAKE_"; - std::string res; - res += RccPathChecksum_; - res += '/'; - res += AppendFilenameSuffix(RccFileName_, suffix); + std::string res = cmStrCat(RccPathChecksum_, '/', + AppendFilenameSuffix(RccFileName_, suffix)); return res; } @@ -192,21 +182,10 @@ bool cmQtAutoRcc::SettingsFileRead() 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; + std::string str = + cmStrCat(RccExecutable_, sep, cmJoin(RccListOptions_, ";"), sep, + QrcFile_, sep, RccPathChecksum_, sep, RccFileName_, sep, + cmJoin(Options_, ";"), sep, cmJoin(Inputs_, ";"), sep); SettingsString_ = crypt.HashString(str); } } @@ -272,9 +251,7 @@ bool cmQtAutoRcc::SettingsFileWrite() Log().Info(GenT::RCC, "Writing settings file " + Quoted(SettingsFile_)); } // Write settings file - std::string content = "rcc:"; - content += SettingsString_; - content += '\n'; + std::string content = cmStrCat("rcc:", SettingsString_, '\n'); std::string error; if (!FileWrite(SettingsFile_, content, &error)) { Log().ErrorFile(GenT::RCC, SettingsFile_, @@ -296,9 +273,8 @@ 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"; + error = + cmStrCat("The resources file ", Quoted(QrcFile_), " does not exist"); Log().ErrorFile(GenT::RCC, QrcFile_, error); return false; } @@ -306,10 +282,8 @@ bool cmQtAutoRcc::TestQrcRccFiles(bool& generate) // 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; @@ -318,10 +292,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; @@ -330,12 +303,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; @@ -344,10 +314,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; @@ -374,21 +343,17 @@ bool cmQtAutoRcc::TestResources(bool& generate) cmFileTime fileTime; if (!fileTime.Load(resFile)) { std::string error; - error = "Could not find the resource file\n "; - error += Quoted(resFile); - error += '\n'; + error = cmStrCat("Could not find the resource file\n ", Quoted(resFile), + '\n'); Log().ErrorFile(GenT::RCC, QrcFile_, error); 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; @@ -402,10 +367,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 = "Touching "; - reason += Quoted(RccFileOutput_); - reason += " because it is older than "; - reason += Quoted(InfoFile()); + std::string reason = + cmStrCat("Touching ", Quoted(RccFileOutput_), + " because it is older than ", Quoted(InfoFile())); Log().Info(GenT::RCC, reason); } // Touch build file @@ -456,10 +420,9 @@ bool cmQtAutoRcc::GenerateRcc() if (!result || (retVal != 0)) { // rcc process failed { - std::string err = "The rcc process failed to compile\n "; - err += Quoted(QrcFile_); - err += "\ninto\n "; - err += Quoted(RccFileOutput_); + 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); } cmSystemTools::RemoveFile(RccFileOutput_); @@ -481,12 +444,10 @@ bool cmQtAutoRcc::GenerateWrapper() // Generate a wrapper source file on demand if (IsMultiConfig()) { // Wrapper file content - std::string content; - content += "// This is an autogenerated configuration wrapper file.\n"; - content += "// Changes will be overwritten.\n"; - content += "#include <"; - content += MultiConfigOutput(); - content += ">\n"; + std::string content = + cmStrCat("// This is an autogenerated configuration wrapper file.\n", + "// Changes will be overwritten.\n", "#include <", + MultiConfigOutput(), ">\n"); // Compare with existing file content bool fileDiffers = true; diff --git a/Source/cmRST.cxx b/Source/cmRST.cxx index 2064275..1f9aae8 100644 --- a/Source/cmRST.cxx +++ b/Source/cmRST.cxx @@ -4,6 +4,7 @@ #include "cmAlgorithms.h" #include "cmRange.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmVersion.h" @@ -341,7 +342,7 @@ void cmRST::OutputMarkupLines(bool inlineMarkup) { for (auto line : this->MarkupLines) { if (!line.empty()) { - line = " " + line; + line = cmStrCat(" ", line); } this->OutputLine(line, inlineMarkup); } diff --git a/Source/cmRemoveCommand.cxx b/Source/cmRemoveCommand.cxx index a64ad8c..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 "cmSystemTools.h" - -class cmExecutionStatus; +#include "cmStringAlgorithms.h" // 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) { @@ -25,13 +24,12 @@ bool cmRemoveCommand::InitialPass(std::vector<std::string> const& args, } // expand the variable - std::vector<std::string> const varArgsExpanded = - cmSystemTools::ExpandedListArgument(cacheValue); + std::vector<std::string> const varArgsExpanded = cmExpandedList(cacheValue); // expand the args // check for REMOVE(VAR v1 v2 ... vn) std::vector<std::string> const argsExpanded = - cmSystemTools::ExpandedLists(args.begin() + 1, args.end()); + cmExpandedLists(args.begin() + 1, args.end()); // now create the new value std::string value; @@ -52,7 +50,7 @@ bool cmRemoveCommand::InitialPass(std::vector<std::string> const& args, } // add the definition - this->Makefile->AddDefinition(variable, value.c_str()); + status.GetMakefile().AddDefinition(variable, value); return true; } diff --git a/Source/cmRemoveCommand.h b/Source/cmRemoveCommand.h index 7b11849..fb72ab5 100644 --- a/Source/cmRemoveCommand.h +++ b/Source/cmRemoveCommand.h @@ -8,29 +8,14 @@ #include <string> #include <vector> -#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. - */ - cmCommand* Clone() override { return new 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/cmRemoveDefinitionsCommand.h b/Source/cmRemoveDefinitionsCommand.h index a5cb204..85d01d4 100644 --- a/Source/cmRemoveDefinitionsCommand.h +++ b/Source/cmRemoveDefinitionsCommand.h @@ -8,6 +8,8 @@ #include <string> #include <vector> +#include "cm_memory.hxx" + #include "cmCommand.h" class cmExecutionStatus; @@ -25,7 +27,10 @@ public: /** * This is a virtual constructor for the command. */ - cmCommand* Clone() override { return new cmRemoveDefinitionsCommand; } + std::unique_ptr<cmCommand> Clone() override + { + return cm::make_unique<cmRemoveDefinitionsCommand>(); + } /** * This is called when the command is first encountered in diff --git a/Source/cmReturnCommand.cxx b/Source/cmReturnCommand.cxx index ceea8b4..5905669 100644 --- a/Source/cmReturnCommand.cxx +++ b/Source/cmReturnCommand.cxx @@ -5,8 +5,8 @@ #include "cmExecutionStatus.h" // cmReturnCommand -bool cmReturnCommand::InitialPass(std::vector<std::string> const&, - cmExecutionStatus& status) +bool cmReturnCommand(std::vector<std::string> const&, + cmExecutionStatus& status) { status.SetReturnInvoked(); return true; diff --git a/Source/cmReturnCommand.h b/Source/cmReturnCommand.h index ef39614..2404a36 100644 --- a/Source/cmReturnCommand.h +++ b/Source/cmReturnCommand.h @@ -8,29 +8,10 @@ #include <string> #include <vector> -#include "cmCommand.h" - class cmExecutionStatus; -/** \class cmReturnCommand - * \brief Return from a directory or function - * - * cmReturnCommand returns from a directory or function - */ -class cmReturnCommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - cmCommand* Clone() override { return new cmReturnCommand; } - - /** - * 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; -}; +/// Return from a directory or function +bool cmReturnCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmRuntimeDependencyArchive.cxx b/Source/cmRuntimeDependencyArchive.cxx new file mode 100644 index 0000000..1b3f387 --- /dev/null +++ b/Source/cmRuntimeDependencyArchive.cxx @@ -0,0 +1,377 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ + +#include "cmRuntimeDependencyArchive.h" + +#include "cmBinUtilsLinuxELFLinker.h" +#include "cmBinUtilsMacOSMachOLinker.h" +#include "cmBinUtilsWindowsPELinker.h" +#include "cmExecutionStatus.h" +#include "cmMakefile.h" +#include "cmStateTypes.h" +#include "cmStringAlgorithms.h" +#include "cmSystemTools.h" + +#if defined(_WIN32) +# include "cmGlobalGenerator.h" +# ifndef CMAKE_BOOTSTRAP +# include "cmGlobalVisualStudioVersionedGenerator.h" +# endif +# include "cmVSSetupHelper.h" +# include "cmsys/Glob.hxx" +#endif + +#include <algorithm> +#include <sstream> +#include <string> +#include <utility> +#include <vector> + +#include "cm_memory.hxx" + +#if defined(_WIN32) +static void AddVisualStudioPath(std::vector<std::string>& paths, + const std::string& prefix, + unsigned int version, cmGlobalGenerator* gg) +{ + // If generating for the VS IDE, use the same instance. + std::string vsloc; + bool found = false; +# ifndef CMAKE_BOOTSTRAP + if (gg->GetName().find(prefix) == 0) { + cmGlobalVisualStudioVersionedGenerator* vsgen = + static_cast<cmGlobalVisualStudioVersionedGenerator*>(gg); + if (vsgen->GetVSInstance(vsloc)) { + found = true; + } + } +# endif + + // Otherwise, find a VS instance ourselves. + if (!found) { + cmVSSetupAPIHelper vsSetupAPIHelper(version); + if (vsSetupAPIHelper.GetVSInstanceInfo(vsloc)) { + cmSystemTools::ConvertToUnixSlashes(vsloc); + found = true; + } + } + + if (found) { + cmsys::Glob glob; + glob.SetListDirs(true); + glob.FindFiles(vsloc + "/VC/Tools/MSVC/*"); + for (auto const& vcdir : glob.GetFiles()) { + paths.push_back(vcdir + "/bin/Hostx64/x64"); + paths.push_back(vcdir + "/bin/Hostx86/x64"); + paths.push_back(vcdir + "/bin/Hostx64/x86"); + paths.push_back(vcdir + "/bin/Hostx86/x86"); + } + } +} + +static void AddRegistryPath(std::vector<std::string>& paths, + const std::string& path, cmMakefile* mf) +{ + // We should view the registry as the target application would view + // it. + cmSystemTools::KeyWOW64 view = cmSystemTools::KeyWOW64_32; + cmSystemTools::KeyWOW64 other_view = cmSystemTools::KeyWOW64_64; + if (mf->PlatformIs64Bit()) { + view = cmSystemTools::KeyWOW64_64; + other_view = cmSystemTools::KeyWOW64_32; + } + + // Expand using the view of the target application. + std::string expanded = path; + cmSystemTools::ExpandRegistryValues(expanded, view); + cmSystemTools::GlobDirs(expanded, paths); + + // Executables can be either 32-bit or 64-bit, so expand using the + // alternative view. + expanded = path; + cmSystemTools::ExpandRegistryValues(expanded, other_view); + cmSystemTools::GlobDirs(expanded, paths); +} + +static void AddEnvPath(std::vector<std::string>& paths, const std::string& var, + const std::string& suffix) +{ + std::string value; + if (cmSystemTools::GetEnv(var, value)) { + paths.push_back(value + suffix); + } +} +#endif + +static cmsys::RegularExpression TransformCompile(const std::string& str) +{ + return cmsys::RegularExpression(str); +} + +cmRuntimeDependencyArchive::cmRuntimeDependencyArchive( + cmExecutionStatus& status, std::vector<std::string> searchDirectories, + std::string bundleExecutable, + const std::vector<std::string>& preIncludeRegexes, + const std::vector<std::string>& preExcludeRegexes, + const std::vector<std::string>& postIncludeRegexes, + const std::vector<std::string>& postExcludeRegexes) + : Status(status) + , SearchDirectories(std::move(searchDirectories)) + , BundleExecutable(std::move(bundleExecutable)) + , PreIncludeRegexes(preIncludeRegexes.size()) + , PreExcludeRegexes(preExcludeRegexes.size()) + , PostIncludeRegexes(postIncludeRegexes.size()) + , PostExcludeRegexes(postExcludeRegexes.size()) +{ + std::transform(preIncludeRegexes.begin(), preIncludeRegexes.end(), + this->PreIncludeRegexes.begin(), TransformCompile); + std::transform(preExcludeRegexes.begin(), preExcludeRegexes.end(), + this->PreExcludeRegexes.begin(), TransformCompile); + std::transform(postIncludeRegexes.begin(), postIncludeRegexes.end(), + this->PostIncludeRegexes.begin(), TransformCompile); + std::transform(postExcludeRegexes.begin(), postExcludeRegexes.end(), + this->PostExcludeRegexes.begin(), TransformCompile); +} + +bool cmRuntimeDependencyArchive::Prepare() +{ + std::string platform = this->GetMakefile()->GetSafeDefinition( + "CMAKE_GET_RUNTIME_DEPENDENCIES_PLATFORM"); + if (platform.empty()) { + std::string systemName = + this->GetMakefile()->GetSafeDefinition("CMAKE_HOST_SYSTEM_NAME"); + if (systemName == "Windows") { + platform = "windows+pe"; + } else if (systemName == "Darwin") { + platform = "macos+macho"; + } else if (systemName == "Linux") { + platform = "linux+elf"; + } + } + if (platform == "linux+elf") { + this->Linker = cm::make_unique<cmBinUtilsLinuxELFLinker>(this); + } else if (platform == "windows+pe") { + this->Linker = cm::make_unique<cmBinUtilsWindowsPELinker>(this); + } else if (platform == "macos+macho") { + this->Linker = cm::make_unique<cmBinUtilsMacOSMachOLinker>(this); + } else { + std::ostringstream e; + e << "Invalid value for CMAKE_GET_RUNTIME_DEPENDENCIES_PLATFORM: " + << platform; + this->SetError(e.str()); + return false; + } + + return this->Linker->Prepare(); +} + +bool cmRuntimeDependencyArchive::GetRuntimeDependencies( + const std::vector<std::string>& executables, + const std::vector<std::string>& libraries, + const std::vector<std::string>& modules) +{ + for (auto const& exe : executables) { + if (!this->Linker->ScanDependencies(exe, cmStateEnums::EXECUTABLE)) { + return false; + } + } + for (auto const& lib : libraries) { + if (!this->Linker->ScanDependencies(lib, cmStateEnums::SHARED_LIBRARY)) { + return false; + } + } + for (auto const& mod : modules) { + if (!this->Linker->ScanDependencies(mod, cmStateEnums::MODULE_LIBRARY)) { + return false; + } + } + + return true; +} + +void cmRuntimeDependencyArchive::SetError(const std::string& e) +{ + this->Status.SetError(e); +} + +std::string cmRuntimeDependencyArchive::GetBundleExecutable() +{ + return this->BundleExecutable; +} + +const std::vector<std::string>& +cmRuntimeDependencyArchive::GetSearchDirectories() +{ + return this->SearchDirectories; +} + +std::string cmRuntimeDependencyArchive::GetGetRuntimeDependenciesTool() +{ + return this->GetMakefile()->GetSafeDefinition( + "CMAKE_GET_RUNTIME_DEPENDENCIES_TOOL"); +} + +bool cmRuntimeDependencyArchive::GetGetRuntimeDependenciesCommand( + const std::string& search, std::vector<std::string>& command) +{ + // First see if it was supplied by the user + std::string toolCommand = this->GetMakefile()->GetSafeDefinition( + "CMAKE_GET_RUNTIME_DEPENDENCIES_COMMAND"); + if (!toolCommand.empty()) { + cmExpandList(toolCommand, command); + return true; + } + + // Now go searching for it + std::vector<std::string> paths; +#ifdef _WIN32 + cmGlobalGenerator* gg = this->GetMakefile()->GetGlobalGenerator(); + + // Add newer Visual Studio paths + AddVisualStudioPath(paths, "Visual Studio 16 ", 16, gg); + AddVisualStudioPath(paths, "Visual Studio 15 ", 15, gg); + + // Add older Visual Studio paths + AddRegistryPath( + paths, + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\14.0;InstallDir]/" + "../../VC/bin", + this->GetMakefile()); + AddEnvPath(paths, "VS140COMNTOOLS", "/../../VC/bin"); + paths.push_back( + "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin"); + AddRegistryPath( + paths, + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\12.0;InstallDir]/" + "../../VC/bin", + this->GetMakefile()); + AddEnvPath(paths, "VS120COMNTOOLS", "/../../VC/bin"); + paths.push_back( + "C:/Program Files (x86)/Microsoft Visual Studio 12.0/VC/bin"); + AddRegistryPath( + paths, + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\11.0;InstallDir]/" + "../../VC/bin", + this->GetMakefile()); + AddEnvPath(paths, "VS110COMNTOOLS", "/../../VC/bin"); + paths.push_back( + "C:/Program Files (x86)/Microsoft Visual Studio 11.0/VC/bin"); + AddRegistryPath( + paths, + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\10.0;InstallDir]/" + "../../VC/bin", + this->GetMakefile()); + AddEnvPath(paths, "VS100COMNTOOLS", "/../../VC/bin"); + paths.push_back( + "C:/Program Files (x86)/Microsoft Visual Studio 10.0/VC/bin"); + AddRegistryPath( + paths, + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\9.0;InstallDir]/" + "../../VC/bin", + this->GetMakefile()); + AddEnvPath(paths, "VS90COMNTOOLS", "/../../VC/bin"); + paths.push_back("C:/Program Files/Microsoft Visual Studio 9.0/VC/bin"); + paths.push_back("C:/Program Files (x86)/Microsoft Visual Studio 9.0/VC/bin"); + AddRegistryPath( + paths, + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\8.0;InstallDir]/" + "../../VC/bin", + this->GetMakefile()); + AddEnvPath(paths, "VS80COMNTOOLS", "/../../VC/bin"); + paths.push_back("C:/Program Files/Microsoft Visual Studio 8/VC/BIN"); + paths.push_back("C:/Program Files (x86)/Microsoft Visual Studio 8/VC/BIN"); + AddRegistryPath( + paths, + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\7.1;InstallDir]/" + "../../VC7/bin", + this->GetMakefile()); + AddEnvPath(paths, "VS71COMNTOOLS", "/../../VC7/bin"); + paths.push_back( + "C:/Program Files/Microsoft Visual Studio .NET 2003/VC7/BIN"); + paths.push_back( + "C:/Program Files (x86)/Microsoft Visual Studio .NET 2003/VC7/BIN"); +#endif + + std::string program = cmSystemTools::FindProgram(search, paths); + if (!program.empty()) { + command = { program }; + return true; + } + + // Couldn't find it + return false; +} + +bool cmRuntimeDependencyArchive::IsPreExcluded(const std::string& name) +{ + cmsys::RegularExpressionMatch match; + + for (auto const& regex : this->PreIncludeRegexes) { + if (regex.find(name.c_str(), match)) { + return false; + } + } + + for (auto const& regex : this->PreExcludeRegexes) { + if (regex.find(name.c_str(), match)) { + return true; + } + } + + return false; +} + +bool cmRuntimeDependencyArchive::IsPostExcluded(const std::string& name) +{ + cmsys::RegularExpressionMatch match; + + for (auto const& regex : this->PostIncludeRegexes) { + if (regex.find(name.c_str(), match)) { + return false; + } + } + + for (auto const& regex : this->PostExcludeRegexes) { + if (regex.find(name.c_str(), match)) { + return true; + } + } + + return false; +} + +void cmRuntimeDependencyArchive::AddResolvedPath(const std::string& name, + const std::string& path, + bool& unique) +{ + auto it = this->ResolvedPaths.emplace(name, std::set<std::string>{}).first; + unique = true; + for (auto const& other : it->second) { + if (cmSystemTools::SameFile(path, other)) { + unique = false; + break; + } + } + it->second.insert(path); +} + +void cmRuntimeDependencyArchive::AddUnresolvedPath(const std::string& name) +{ + this->UnresolvedPaths.insert(name); +} + +cmMakefile* cmRuntimeDependencyArchive::GetMakefile() +{ + return &this->Status.GetMakefile(); +} + +const std::map<std::string, std::set<std::string>>& +cmRuntimeDependencyArchive::GetResolvedPaths() +{ + return this->ResolvedPaths; +} + +const std::set<std::string>& cmRuntimeDependencyArchive::GetUnresolvedPaths() +{ + return this->UnresolvedPaths; +} diff --git a/Source/cmRuntimeDependencyArchive.h b/Source/cmRuntimeDependencyArchive.h new file mode 100644 index 0000000..e063121 --- /dev/null +++ b/Source/cmRuntimeDependencyArchive.h @@ -0,0 +1,70 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ + +#ifndef cmRuntimeDependencyArchive_h +#define cmRuntimeDependencyArchive_h + +#include "cmBinUtilsLinker.h" + +#include "cmsys/RegularExpression.hxx" + +#include <map> +#include <memory> +#include <set> +#include <string> +#include <vector> + +class cmExecutionStatus; +class cmMakefile; + +class cmRuntimeDependencyArchive +{ +public: + explicit cmRuntimeDependencyArchive( + cmExecutionStatus& status, std::vector<std::string> searchDirectories, + std::string bundleExecutable, + const std::vector<std::string>& preIncludeRegexes, + const std::vector<std::string>& preExcludeRegexes, + const std::vector<std::string>& postIncludeRegexes, + const std::vector<std::string>& postExcludeRegexes); + bool Prepare(); + bool GetRuntimeDependencies(const std::vector<std::string>& executables, + const std::vector<std::string>& libraries, + const std::vector<std::string>& modules); + + void SetError(const std::string& e); + + std::string GetBundleExecutable(); + const std::vector<std::string>& GetSearchDirectories(); + std::string GetGetRuntimeDependenciesTool(); + bool GetGetRuntimeDependenciesCommand(const std::string& search, + std::vector<std::string>& command); + bool IsPreExcluded(const std::string& name); + bool IsPostExcluded(const std::string& name); + + void AddResolvedPath(const std::string& name, const std::string& path, + bool& unique); + void AddUnresolvedPath(const std::string& name); + + cmMakefile* GetMakefile(); + const std::map<std::string, std::set<std::string>>& GetResolvedPaths(); + const std::set<std::string>& GetUnresolvedPaths(); + +private: + cmExecutionStatus& Status; + std::unique_ptr<cmBinUtilsLinker> Linker; + + std::string GetRuntimeDependenciesTool; + std::vector<std::string> GetRuntimeDependenciesCommand; + + std::vector<std::string> SearchDirectories; + std::string BundleExecutable; + std::vector<cmsys::RegularExpression> PreIncludeRegexes; + std::vector<cmsys::RegularExpression> PreExcludeRegexes; + std::vector<cmsys::RegularExpression> PostIncludeRegexes; + std::vector<cmsys::RegularExpression> PostExcludeRegexes; + std::map<std::string, std::set<std::string>> ResolvedPaths; + std::set<std::string> UnresolvedPaths; +}; + +#endif // cmRuntimeDependencyArchive_h 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 f98984e..d15ce57 100644 --- a/Source/cmSearchPath.cxx +++ b/Source/cmSearchPath.cxx @@ -6,9 +6,9 @@ #include <cassert> #include <utility> -#include "cmAlgorithms.h" #include "cmFindCommon.h" #include "cmMakefile.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" cmSearchPath::cmSearchPath(cmFindCommon* findCmd) @@ -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; - cmSystemTools::ExpandListArgument(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; - cmSystemTools::ExpandListArgument(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 28cbdc0..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.c_str()); + status.GetMakefile().AddDefinition(var, value); } } else { // Parse the command line. @@ -97,7 +96,7 @@ bool cmSeparateArgumentsCommand::InitialPass( value += si; } } - this->Makefile->AddDefinition(var, value.c_str()); + status.GetMakefile().AddDefinition(var, value); } return true; diff --git a/Source/cmSeparateArgumentsCommand.h b/Source/cmSeparateArgumentsCommand.h index 988ad23..e000c51 100644 --- a/Source/cmSeparateArgumentsCommand.h +++ b/Source/cmSeparateArgumentsCommand.h @@ -8,29 +8,14 @@ #include <string> #include <vector> -#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. - */ - cmCommand* Clone() override { return new 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/cmServer.cxx b/Source/cmServer.cxx index 1903fd9..9df1883 100644 --- a/Source/cmServer.cxx +++ b/Source/cmServer.cxx @@ -2,7 +2,6 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmServer.h" -#include "cmAlgorithms.h" #include "cmConnection.h" #include "cmFileMonitor.h" #include "cmJsonObjectDictionary.h" @@ -18,10 +17,11 @@ #include <cassert> #include <cstdint> #include <iostream> -#include <memory> #include <mutex> #include <utility> +#include "cm_memory.hxx" + void on_signal(uv_signal_t* signal, int signum) { auto conn = static_cast<cmServerBase*>(signal->data); diff --git a/Source/cmServer.h b/Source/cmServer.h index aba4924..ab2ad23 100644 --- a/Source/cmServer.h +++ b/Source/cmServer.h @@ -10,7 +10,7 @@ #include "cmUVHandlePtr.h" -#include <memory> // IWYU pragma: keep +#include <memory> #include <string> #include <vector> diff --git a/Source/cmServerProtocol.cxx b/Source/cmServerProtocol.cxx index 558391f..670161d 100644 --- a/Source/cmServerProtocol.cxx +++ b/Source/cmServerProtocol.cxx @@ -19,11 +19,12 @@ #include <algorithm> #include <cassert> #include <functional> -#include <memory> #include <string> #include <utility> #include <vector> +#include "cm_memory.hxx" + // Get rid of some windows macros: #undef max @@ -378,8 +379,7 @@ void cmServerProtocol1::HandleCMakeFileChanges(const std::string& path, SendSignal(kFILE_CHANGE_SIGNAL, obj); } -const cmServerResponse cmServerProtocol1::Process( - const cmServerRequest& request) +cmServerResponse cmServerProtocol1::Process(const cmServerRequest& request) { assert(this->m_State >= STATE_ACTIVE); @@ -434,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/cmServerProtocol.h b/Source/cmServerProtocol.h index 2f55a20..5da4344 100644 --- a/Source/cmServerProtocol.h +++ b/Source/cmServerProtocol.h @@ -80,7 +80,7 @@ public: virtual std::pair<int, int> ProtocolVersion() const = 0; virtual bool IsExperimental() const = 0; - virtual const cmServerResponse Process(const cmServerRequest& request) = 0; + virtual cmServerResponse Process(const cmServerRequest& request) = 0; bool Activate(cmServer* server, const cmServerRequest& request, std::string* errorMessage); @@ -106,7 +106,7 @@ class cmServerProtocol1 : public cmServerProtocol public: std::pair<int, int> ProtocolVersion() const override; bool IsExperimental() const override; - const cmServerResponse Process(const cmServerRequest& request) override; + cmServerResponse Process(const cmServerRequest& request) override; private: bool DoActivate(const cmServerRequest& request, diff --git a/Source/cmSetCommand.cxx b/Source/cmSetCommand.cxx index 41555e8..8c3a4cb 100644 --- a/Source/cmSetCommand.cxx +++ b/Source/cmSetCommand.cxx @@ -2,22 +2,21 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmSetCommand.h" -#include "cmAlgorithms.h" +#include "cmExecutionStatus.h" #include "cmMakefile.h" #include "cmMessageType.h" #include "cmRange.h" #include "cmState.h" #include "cmStateTypes.h" +#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.c_str()); + status.GetMakefile().AddDefinition(variable, value); } return true; } diff --git a/Source/cmSetCommand.h b/Source/cmSetCommand.h index 76e3eae..0973d33 100644 --- a/Source/cmSetCommand.h +++ b/Source/cmSetCommand.h @@ -8,29 +8,14 @@ #include <string> #include <vector> -#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. - */ - cmCommand* Clone() override { return new 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 473347c..c243dd7 100644 --- a/Source/cmSetDirectoryPropertiesCommand.h +++ b/Source/cmSetDirectoryPropertiesCommand.h @@ -8,30 +8,9 @@ #include <string> #include <vector> -#include "cmCommand.h" - class cmExecutionStatus; -class cmMakefile; - -class cmSetDirectoryPropertiesCommand : public cmCommand -{ -public: - cmCommand* Clone() override { return new 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 e9343c7..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" @@ -11,25 +13,72 @@ #include "cmRange.h" #include "cmSourceFile.h" #include "cmState.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmTarget.h" #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; } @@ -55,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 { @@ -74,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: @@ -130,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."); @@ -189,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; } @@ -299,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 && !cmSystemTools::IsOn(this->PropertyValue) && - !cmSystemTools::IsOff(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 f1126bb..ec36f84 100644 --- a/Source/cmSetPropertyCommand.h +++ b/Source/cmSetPropertyCommand.h @@ -5,53 +5,12 @@ #include "cmConfigure.h" // IWYU pragma: keep -#include <set> #include <string> #include <vector> -#include "cmCommand.h" - class cmExecutionStatus; -class cmInstalledFile; -class cmSourceFile; -class cmTarget; -class cmTest; - -class cmSetPropertyCommand : public cmCommand -{ -public: - cmSetPropertyCommand(); - - cmCommand* Clone() override { return new 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/cmSetSourceFilesPropertiesCommand.cxx b/Source/cmSetSourceFilesPropertiesCommand.cxx index 9388e7c..8e3217f 100644 --- a/Source/cmSetSourceFilesPropertiesCommand.cxx +++ b/Source/cmSetSourceFilesPropertiesCommand.cxx @@ -4,7 +4,7 @@ #include "cmMakefile.h" #include "cmSourceFile.h" -#include "cmSystemTools.h" +#include "cmStringAlgorithms.h" class cmExecutionStatus; @@ -87,7 +87,7 @@ bool cmSetSourceFilesPropertiesCommand::RunCommand( propertyPairs.push_back(*j); if (*j == "GENERATED") { ++j; - if (j != propend && cmSystemTools::IsOn(*j)) { + if (j != propend && cmIsOn(*j)) { generated = true; } } else { diff --git a/Source/cmSetSourceFilesPropertiesCommand.h b/Source/cmSetSourceFilesPropertiesCommand.h index afb19f6..6fd6c41 100644 --- a/Source/cmSetSourceFilesPropertiesCommand.h +++ b/Source/cmSetSourceFilesPropertiesCommand.h @@ -8,6 +8,8 @@ #include <string> #include <vector> +#include "cm_memory.hxx" + #include "cmCommand.h" class cmExecutionStatus; @@ -16,7 +18,10 @@ class cmMakefile; class cmSetSourceFilesPropertiesCommand : public cmCommand { public: - cmCommand* Clone() override { return new cmSetSourceFilesPropertiesCommand; } + std::unique_ptr<cmCommand> Clone() override + { + return cm::make_unique<cmSetSourceFilesPropertiesCommand>(); + } /** * This is called when the command is first encountered in 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/cmSetTargetPropertiesCommand.h b/Source/cmSetTargetPropertiesCommand.h index c9755da..7e4606e 100644 --- a/Source/cmSetTargetPropertiesCommand.h +++ b/Source/cmSetTargetPropertiesCommand.h @@ -8,6 +8,8 @@ #include <string> #include <vector> +#include "cm_memory.hxx" + #include "cmCommand.h" class cmExecutionStatus; @@ -16,7 +18,10 @@ class cmMakefile; class cmSetTargetPropertiesCommand : public cmCommand { public: - cmCommand* Clone() override { return new cmSetTargetPropertiesCommand; } + std::unique_ptr<cmCommand> Clone() override + { + return cm::make_unique<cmSetTargetPropertiesCommand>(); + } /** * This is called when the command is first encountered in 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/cmSetTestsPropertiesCommand.h b/Source/cmSetTestsPropertiesCommand.h index 84b2645..d73e95a 100644 --- a/Source/cmSetTestsPropertiesCommand.h +++ b/Source/cmSetTestsPropertiesCommand.h @@ -8,6 +8,8 @@ #include <string> #include <vector> +#include "cm_memory.hxx" + #include "cmCommand.h" class cmExecutionStatus; @@ -16,7 +18,10 @@ class cmMakefile; class cmSetTestsPropertiesCommand : public cmCommand { public: - cmCommand* Clone() override { return new cmSetTestsPropertiesCommand; } + std::unique_ptr<cmCommand> Clone() override + { + return cm::make_unique<cmSetTestsPropertiesCommand>(); + } /** * This is called when the command is first encountered in diff --git a/Source/cmSiteNameCommand.cxx b/Source/cmSiteNameCommand.cxx index 9f041bc..d47f121 100644 --- a/Source/cmSiteNameCommand.cxx +++ b/Source/cmSiteNameCommand.cxx @@ -4,18 +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; @@ -26,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; @@ -50,7 +50,7 @@ bool cmSiteNameCommand::InitialPass(std::vector<std::string> const& args, } #else // try to find the hostname for this computer - if (!cmSystemTools::IsOff(hostname_cmd)) { + if (!cmIsOff(hostname_cmd)) { std::string host; cmSystemTools::RunSingleCommand(hostname_cmd, &host, nullptr, nullptr, nullptr, cmSystemTools::OUTPUT_NONE); @@ -71,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 2d8dc17..e8fc608 100644 --- a/Source/cmSiteNameCommand.h +++ b/Source/cmSiteNameCommand.h @@ -8,29 +8,14 @@ #include <string> #include <vector> -#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. - */ - cmCommand* Clone() override { return new 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 d05fb68..a6d2807 100644 --- a/Source/cmSourceFile.cxx +++ b/Source/cmSourceFile.cxx @@ -11,6 +11,7 @@ #include "cmMessageType.h" #include "cmProperty.h" #include "cmState.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmake.h" @@ -150,9 +151,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; @@ -177,10 +176,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 += " ."; @@ -242,7 +239,7 @@ void cmSourceFile::SetProperty(const std::string& prop, const char* value) // Update IsGenerated flag if (prop == propGENERATED) { - this->IsGenerated = cmSystemTools::IsOn(value); + this->IsGenerated = cmIsOn(value); } } @@ -316,7 +313,7 @@ const char* cmSourceFile::GetSafeProperty(const std::string& prop) const bool cmSourceFile::GetPropertyAsBool(const std::string& prop) const { - return cmSystemTools::IsOn(this->GetProperty(prop)); + return cmIsOn(this->GetProperty(prop)); } cmCustomCommand* cmSourceFile::GetCustomCommand() diff --git a/Source/cmSourceFileLocation.cxx b/Source/cmSourceFileLocation.cxx index acacba2..0e8d09d 100644 --- a/Source/cmSourceFileLocation.cxx +++ b/Source/cmSourceFileLocation.cxx @@ -2,10 +2,10 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmSourceFileLocation.h" -#include "cmAlgorithms.h" #include "cmGlobalGenerator.h" #include "cmMakefile.h" #include "cmMessageType.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmake.h" @@ -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; @@ -146,8 +145,7 @@ bool cmSourceFileLocation::MatchesAmbiguousExtension( // adding an extension. if (!(this->Name.size() > loc.Name.size() && this->Name[loc.Name.size()] == '.' && - cmHasLiteralPrefixImpl(this->Name.c_str(), loc.Name.c_str(), - loc.Name.size()))) { + cmHasPrefix(this->Name, loc.Name))) { return false; } 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 04b4d72..399f1da 100644 --- a/Source/cmSourceGroupCommand.cxx +++ b/Source/cmSourceGroupCommand.cxx @@ -2,13 +2,14 @@ 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" #include "cmSystemTools.h" namespace { @@ -20,7 +21,7 @@ const std::string kSourceGroupOptionName = "<sg_name>"; std::vector<std::string> tokenizePath(const std::string& path) { - return cmSystemTools::tokenize(path, "\\/"); + return cmTokenize(path, "\\/"); } std::string getFullFilePath(const std::string& currentPath, @@ -29,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); @@ -54,8 +53,8 @@ bool rootIsPrefix(const std::string& root, const std::vector<std::string>& files, std::string& error) { for (std::string const& file : files) { - if (!cmSystemTools::StringStartsWith(file, root.c_str())) { - error = "ROOT: " + root + " is not a prefix of file: " + file; + if (!cmHasPrefix(file, root)) { + error = cmStrCat("ROOT: ", root, " is not a prefix of file: ", file); return false; } } @@ -93,7 +92,7 @@ bool addFilesToItsSourceGroups(const std::string& root, std::vector<std::string> tokenizedPath; if (!prefix.empty()) { - tokenizedPath = tokenizePath(prefix + '/' + sgFilesPath); + tokenizedPath = tokenizePath(cmStrCat(prefix, '/', sgFilesPath)); } else { tokenizedPath = tokenizePath(sgFilesPath); } @@ -139,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( @@ -236,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/cmSourceGroupCommand.h b/Source/cmSourceGroupCommand.h index ec5ad32..eec4ec0 100644 --- a/Source/cmSourceGroupCommand.h +++ b/Source/cmSourceGroupCommand.h @@ -9,6 +9,8 @@ #include <string> #include <vector> +#include "cm_memory.hxx" + #include "cmCommand.h" class cmExecutionStatus; @@ -25,7 +27,10 @@ public: /** * This is a virtual constructor for the command. */ - cmCommand* Clone() override { return new cmSourceGroupCommand; } + std::unique_ptr<cmCommand> Clone() override + { + return cm::make_unique<cmSourceGroupCommand>(); + } /** * This is called when the command is first encountered in diff --git a/Source/cmState.cxx b/Source/cmState.cxx index fa7df0b..b6f1808 100644 --- a/Source/cmState.cxx +++ b/Source/cmState.cxx @@ -5,35 +5,34 @@ #include "cmsys/RegularExpression.hxx" #include <algorithm> #include <assert.h> +#include <stdlib.h> #include <string.h> #include <utility> -#include "cmAlgorithms.h" +#include "cm_memory.hxx" + #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" #include "cmSystemTools.h" -#include "cmUnexpectedCommand.h" #include "cmake.h" cmState::cmState() { - this->CacheManager = new cmCacheManager; - this->GlobVerificationManager = new cmGlobVerificationManager; + this->CacheManager = cm::make_unique<cmCacheManager>(); + this->GlobVerificationManager = cm::make_unique<cmGlobVerificationManager>(); } -cmState::~cmState() -{ - delete this->CacheManager; - delete this->GlobVerificationManager; - cmDeleteAll(this->BuiltinCommands); - cmDeleteAll(this->ScriptedCommands); -} +cmState::~cmState() = default; const char* cmState::GetTargetTypeName(cmStateEnums::TargetType targetType) { @@ -267,7 +266,7 @@ void cmState::RemoveCacheEntryProperty(std::string const& key, cmStateSnapshot cmState::Reset() { - this->GlobalProperties.clear(); + this->GlobalProperties.Clear(); this->PropertyDefinitions.clear(); this->GlobVerificationManager->Reset(); @@ -289,7 +288,7 @@ cmStateSnapshot cmState::Reset() it->LinkDirectoriesBacktraces.clear(); it->DirectoryEnd = pos; it->NormalTargetNames.clear(); - it->Properties.clear(); + it->Properties.Clear(); it->Children.clear(); } @@ -310,8 +309,8 @@ cmStateSnapshot cmState::Reset() pos->Parent = this->VarTree.Root(); pos->Root = this->VarTree.Root(); - pos->Vars->Set("CMAKE_SOURCE_DIR", srcDir.c_str()); - pos->Vars->Set("CMAKE_BINARY_DIR", binDir.c_str()); + pos->Vars->Set("CMAKE_SOURCE_DIR", srcDir); + pos->Vars->Set("CMAKE_BINARY_DIR", binDir); } this->DefineProperty("RULE_LAUNCH_COMPILE", cmProperty::DIRECTORY, "", "", @@ -421,61 +420,117 @@ void cmState::SetIsGeneratorMultiConfig(bool b) this->IsGeneratorMultiConfig = b; } -void cmState::AddBuiltinCommand(std::string const& name, cmCommand* command) +void cmState::AddBuiltinCommand(std::string const& name, + std::unique_ptr<cmCommand> command) +{ + this->AddBuiltinCommand(name, cmLegacyCommandWrapper(std::move(command))); +} + +void cmState::AddBuiltinCommand(std::string const& name, Command command) { assert(name == cmSystemTools::LowerCase(name)); assert(this->BuiltinCommands.find(name) == this->BuiltinCommands.end()); - this->BuiltinCommands.insert(std::make_pair(name, 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::AddDisallowedCommand(std::string const& name, cmCommand* command, +void cmState::AddBuiltinCommand(std::string const& name, + BuiltinCommand command) +{ + this->AddBuiltinCommand( + name, + [command](const std::vector<cmListFileArgument>& args, + cmExecutionStatus& status) -> bool { + return InvokeBuiltinCommand(command, args, status); + }); +} + +void cmState::AddDisallowedCommand(std::string const& name, + BuiltinCommand command, cmPolicies::PolicyID policy, const char* message) { - this->AddBuiltinCommand(name, - new cmDisallowedCommand(command, policy, message)); + this->AddBuiltinCommand( + name, + [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::AddDisallowedCommand(std::string const& name, + std::unique_ptr<cmCommand> command, + cmPolicies::PolicyID policy, + const char* message) +{ + this->AddBuiltinCommand( + name, + cm::make_unique<cmDisallowedCommand>(std::move(command), policy, message)); } void cmState::AddUnexpectedCommand(std::string const& name, const char* error) { - this->AddBuiltinCommand(name, new cmUnexpectedCommand(name, error)); + this->AddBuiltinCommand( + name, + [name, error](std::vector<cmListFileArgument> const&, + cmExecutionStatus& status) -> bool { + const char* versionValue = + status.GetMakefile().GetDefinition("CMAKE_MINIMUM_REQUIRED_VERSION"); + if (name == "endif" && (!versionValue || atof(versionValue) <= 1.4)) { + return true; + } + status.SetError(error); + return false; + }); } -void cmState::AddScriptedCommand(std::string const& name, cmCommand* command) +void cmState::AddScriptedCommand(std::string const& name, Command command) { std::string sName = cmSystemTools::LowerCase(name); // if the command already exists, give a new name to the old command. - if (cmCommand* oldCmd = this->GetCommand(sName)) { - std::string const newName = "_" + sName; - std::map<std::string, cmCommand*>::iterator pos = - this->ScriptedCommands.find(newName); - if (pos != this->ScriptedCommands.end()) { - delete pos->second; - this->ScriptedCommands.erase(pos); - } - this->ScriptedCommands.insert(std::make_pair(newName, oldCmd->Clone())); + if (Command oldCmd = this->GetCommand(sName)) { + this->ScriptedCommands["_" + sName] = oldCmd; } - // if the command already exists, free the old one - std::map<std::string, cmCommand*>::iterator pos = - this->ScriptedCommands.find(sName); - if (pos != this->ScriptedCommands.end()) { - delete pos->second; - this->ScriptedCommands.erase(pos); - } - this->ScriptedCommands.insert(std::make_pair(sName, command)); + this->ScriptedCommands[sName] = std::move(command); } -cmCommand* cmState::GetCommand(std::string const& name) const +cmState::Command cmState::GetCommand(std::string const& name) const { return GetCommandByExactName(cmSystemTools::LowerCase(name)); } -cmCommand* cmState::GetCommandByExactName(std::string const& name) const +cmState::Command cmState::GetCommandByExactName(std::string const& name) const { - std::map<std::string, cmCommand*>::const_iterator pos; - pos = this->ScriptedCommands.find(name); + auto pos = this->ScriptedCommands.find(name); if (pos != this->ScriptedCommands.end()) { return pos->second; } @@ -506,16 +561,11 @@ std::vector<std::string> cmState::GetCommandNames() const void cmState::RemoveBuiltinCommand(std::string const& name) { assert(name == cmSystemTools::LowerCase(name)); - std::map<std::string, cmCommand*>::iterator i = - this->BuiltinCommands.find(name); - assert(i != this->BuiltinCommands.end()); - delete i->second; - this->BuiltinCommands.erase(i); + this->BuiltinCommands.erase(name); } void cmState::RemoveUserDefinedCommands() { - cmDeleteAll(this->ScriptedCommands); this->ScriptedCommands.clear(); } @@ -584,7 +634,7 @@ const char* cmState::GetGlobalProperty(const std::string& prop) bool cmState::GetGlobalPropertyAsBool(const std::string& prop) { - return cmSystemTools::IsOn(this->GetGlobalProperty(prop)); + return cmIsOn(this->GetGlobalProperty(prop)); } void cmState::SetSourceDirectory(std::string const& sourceDirectory) diff --git a/Source/cmState.h b/Source/cmState.h index 6abe71c..937ab61 100644 --- a/Source/cmState.h +++ b/Source/cmState.h @@ -5,7 +5,9 @@ #include "cmConfigure.h" // IWYU pragma: keep +#include <functional> #include <map> +#include <memory> #include <set> #include <string> #include <vector> @@ -26,6 +28,7 @@ class cmGlobVerificationManager; class cmPropertyDefinition; class cmStateSnapshot; class cmMessenger; +class cmExecutionStatus; class cmState { @@ -140,16 +143,27 @@ public: bool GetIsGeneratorMultiConfig() const; void SetIsGeneratorMultiConfig(bool b); + using Command = std::function<bool(std::vector<cmListFileArgument> const&, + cmExecutionStatus&)>; + using BuiltinCommand = bool (*)(std::vector<std::string> const&, + cmExecutionStatus&); + // Returns a command from its name, case insensitive, or nullptr - cmCommand* GetCommand(std::string const& name) const; + Command GetCommand(std::string const& name) const; // Returns a command from its name, or nullptr - cmCommand* GetCommandByExactName(std::string const& name) const; + Command GetCommandByExactName(std::string const& name) const; - void AddBuiltinCommand(std::string const& name, cmCommand* command); - void AddDisallowedCommand(std::string const& name, cmCommand* command, + void AddBuiltinCommand(std::string const& name, + 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, BuiltinCommand command, + cmPolicies::PolicyID policy, const char* message); + void AddDisallowedCommand(std::string const& name, + std::unique_ptr<cmCommand> command, cmPolicies::PolicyID policy, const char* message); void AddUnexpectedCommand(std::string const& name, const char* error); - void AddScriptedCommand(std::string const& name, cmCommand* command); + void AddScriptedCommand(std::string const& name, Command command); void RemoveBuiltinCommand(std::string const& name); void RemoveUserDefinedCommands(); std::vector<std::string> GetCommandNames() const; @@ -208,11 +222,11 @@ private: std::map<cmProperty::ScopeType, cmPropertyDefinitionMap> PropertyDefinitions; std::vector<std::string> EnabledLanguages; - std::map<std::string, cmCommand*> BuiltinCommands; - std::map<std::string, cmCommand*> ScriptedCommands; + std::map<std::string, Command> BuiltinCommands; + std::map<std::string, Command> ScriptedCommands; cmPropertyMap GlobalProperties; - cmCacheManager* CacheManager; - cmGlobVerificationManager* GlobVerificationManager; + std::unique_ptr<cmCacheManager> CacheManager; + std::unique_ptr<cmGlobVerificationManager> GlobVerificationManager; cmLinkedTree<cmStateDetail::BuildsystemDirectoryStateType> BuildsystemDirectory; diff --git a/Source/cmStateDirectory.cxx b/Source/cmStateDirectory.cxx index 182d3fe..df96bd3 100644 --- a/Source/cmStateDirectory.cxx +++ b/Source/cmStateDirectory.cxx @@ -6,7 +6,7 @@ #include <algorithm> #include <assert.h> #include <iterator> -#include <utility> +#include <vector> #include "cmAlgorithms.h" #include "cmProperty.h" @@ -662,17 +662,12 @@ const char* cmStateDirectory::GetProperty(const std::string& prop, bool cmStateDirectory::GetPropertyAsBool(const std::string& prop) const { - return cmSystemTools::IsOn(this->GetProperty(prop)); + return cmIsOn(this->GetProperty(prop)); } std::vector<std::string> cmStateDirectory::GetPropertyKeys() const { - std::vector<std::string> keys; - keys.reserve(this->DirectoryState->Properties.size()); - for (auto const& it : this->DirectoryState->Properties) { - keys.push_back(it.first); - } - return keys; + return this->DirectoryState->Properties.GetKeys(); } void cmStateDirectory::AddNormalTargetName(std::string const& name) diff --git a/Source/cmStateDirectory.h b/Source/cmStateDirectory.h index 6956594..fe15563 100644 --- a/Source/cmStateDirectory.h +++ b/Source/cmStateDirectory.h @@ -14,6 +14,7 @@ #include "cmListFileCache.h" #include "cmStatePrivate.h" #include "cmStateSnapshot.h" +#include "cmStringAlgorithms.h" class cmStateDirectory { diff --git a/Source/cmStateSnapshot.cxx b/Source/cmStateSnapshot.cxx index 63bec71..121923d 100644 --- a/Source/cmStateSnapshot.cxx +++ b/Source/cmStateSnapshot.cxx @@ -222,14 +222,14 @@ bool cmStateSnapshot::IsInitialized(std::string const& name) const } void cmStateSnapshot::SetDefinition(std::string const& name, - std::string const& value) + cm::string_view value) { - this->Position->Vars->Set(name, value.c_str()); + this->Position->Vars->Set(name, value); } void cmStateSnapshot::RemoveDefinition(std::string const& name) { - this->Position->Vars->Set(name, nullptr); + this->Position->Vars->Unset(name); } std::vector<std::string> cmStateSnapshot::UnusedKeys() const @@ -264,7 +264,11 @@ bool cmStateSnapshot::RaiseScope(std::string const& var, const char* varDef) cmDefinitions::Raise(var, this->Position->Vars, this->Position->Root); // Now update the definition in the parent scope. - this->Position->Parent->Set(var, varDef); + if (varDef) { + this->Position->Parent->Set(var, varDef); + } else { + this->Position->Parent->Unset(var); + } return true; } @@ -324,7 +328,7 @@ void cmStateSnapshot::SetDefaultDefinitions() #if defined(__CYGWIN__) std::string legacy; if (cmSystemTools::GetEnv("CMAKE_LEGACY_CYGWIN_WIN32", legacy) && - cmSystemTools::IsOn(legacy.c_str())) { + cmIsOn(legacy.c_str())) { this->SetDefinition("WIN32", "1"); this->SetDefinition("CMAKE_HOST_WIN32", "1"); } diff --git a/Source/cmStateSnapshot.h b/Source/cmStateSnapshot.h index c315f48..da39127 100644 --- a/Source/cmStateSnapshot.h +++ b/Source/cmStateSnapshot.h @@ -9,6 +9,8 @@ #include <string> #include <vector> +#include "cm_string_view.hxx" + #include "cmLinkedTree.h" #include "cmPolicies.h" #include "cmStateTypes.h" @@ -24,7 +26,7 @@ public: std::string const* GetDefinition(std::string const& name) const; bool IsInitialized(std::string const& name) const; - void SetDefinition(std::string const& name, std::string const& value); + void SetDefinition(std::string const& name, cm::string_view value); void RemoveDefinition(std::string const& name); std::vector<std::string> UnusedKeys() const; std::vector<std::string> ClosureKeys() const; diff --git a/Source/cmStringAlgorithms.cxx b/Source/cmStringAlgorithms.cxx new file mode 100644 index 0000000..c686aa0 --- /dev/null +++ b/Source/cmStringAlgorithms.cxx @@ -0,0 +1,324 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#include "cmStringAlgorithms.h" + +#include <algorithm> +#include <cstdio> +#include <errno.h> +#include <stdlib.h> + +std::string cmTrimWhitespace(cm::string_view str) +{ + auto start = str.begin(); + while (start != str.end() && cmIsSpace(*start)) { + ++start; + } + if (start == str.end()) { + return std::string(); + } + auto stop = str.end() - 1; + while (cmIsSpace(*stop)) { + --stop; + } + return std::string(start, stop + 1); +} + +std::string cmRemoveQuotes(cm::string_view str) +{ + // We process only strings that have two quotes at least. + // Also front() and back() are only defined behavior on non empty strings. + if (str.size() >= 2 && // + str.front() == '"' && // + str.back() == '"') { + // Remove a quote from the front and back + str.remove_prefix(1); + str.remove_suffix(1); + } + return std::string(str); +} + +std::string cmEscapeQuotes(cm::string_view str) +{ + std::string result; + result.reserve(str.size()); + for (const char ch : str) { + if (ch == '"') { + result += '\\'; + } + result += ch; + } + return result; +} + +std::vector<std::string> cmTokenize(cm::string_view str, cm::string_view sep) +{ + std::vector<std::string> tokens; + cm::string_view::size_type tokend = 0; + + do { + cm::string_view::size_type tokstart = str.find_first_not_of(sep, tokend); + if (tokstart == cm::string_view::npos) { + break; // no more tokens + } + tokend = str.find_first_of(sep, tokstart); + if (tokend == cm::string_view::npos) { + tokens.emplace_back(str.substr(tokstart)); + } else { + tokens.emplace_back(str.substr(tokstart, tokend - tokstart)); + } + } while (tokend != cm::string_view::npos); + + if (tokens.empty()) { + tokens.emplace_back(); + } + return tokens; +} + +void cmExpandList(cm::string_view arg, std::vector<std::string>& argsOut, + bool emptyArgs) +{ + // If argument is empty, it is an empty list. + if (!emptyArgs && arg.empty()) { + return; + } + + // if there are no ; in the name then just copy the current string + if (arg.find(';') == cm::string_view::npos) { + argsOut.emplace_back(arg); + return; + } + + std::string newArg; + // Break the string at non-escaped semicolons not nested in []. + int squareNesting = 0; + cm::string_view::iterator last = arg.begin(); + cm::string_view::iterator const cend = arg.end(); + for (cm::string_view::iterator c = last; c != cend; ++c) { + switch (*c) { + case '\\': { + // We only want to allow escaping of semicolons. Other + // escapes should not be processed here. + cm::string_view::iterator cnext = c + 1; + if ((cnext != cend) && *cnext == ';') { + newArg.append(last, c); + // Skip over the escape character + last = cnext; + c = cnext; + } + } break; + case '[': { + ++squareNesting; + } break; + case ']': { + --squareNesting; + } break; + case ';': { + // Break the string here if we are not nested inside square + // brackets. + if (squareNesting == 0) { + newArg.append(last, c); + // Skip over the semicolon + last = c + 1; + if (!newArg.empty() || emptyArgs) { + // Add the last argument if the string is not empty. + argsOut.push_back(newArg); + newArg.clear(); + } + } + } break; + default: { + // Just append this character. + } break; + } + } + newArg.append(last, cend); + if (!newArg.empty() || emptyArgs) { + // Add the last argument if the string is not empty. + argsOut.push_back(std::move(newArg)); + } +} + +std::vector<std::string> cmExpandedList(cm::string_view arg, bool emptyArgs) +{ + std::vector<std::string> argsOut; + cmExpandList(arg, argsOut, emptyArgs); + return argsOut; +} + +namespace { +template <std::size_t N, typename T> +inline void MakeDigits(cm::string_view& view, char (&digits)[N], + const char* pattern, T value) +{ + int res = std::snprintf(digits, N, pattern, value); + if (res > 0 && res < static_cast<int>(N)) { + view = cm::string_view(digits, static_cast<std::size_t>(res)); + } +} +} // unnamed namespace + +cmAlphaNum::cmAlphaNum(int val) +{ + MakeDigits(View_, Digits_, "%i", val); +} + +cmAlphaNum::cmAlphaNum(unsigned int val) +{ + MakeDigits(View_, Digits_, "%u", val); +} + +cmAlphaNum::cmAlphaNum(long int val) +{ + MakeDigits(View_, Digits_, "%li", val); +} + +cmAlphaNum::cmAlphaNum(unsigned long int val) +{ + MakeDigits(View_, Digits_, "%lu", val); +} + +cmAlphaNum::cmAlphaNum(long long int val) +{ + MakeDigits(View_, Digits_, "%lli", val); +} + +cmAlphaNum::cmAlphaNum(unsigned long long int val) +{ + MakeDigits(View_, Digits_, "%llu", val); +} + +cmAlphaNum::cmAlphaNum(float val) +{ + MakeDigits(View_, Digits_, "%g", static_cast<double>(val)); +} + +cmAlphaNum::cmAlphaNum(double val) +{ + MakeDigits(View_, Digits_, "%g", val); +} + +std::string cmCatViews(std::initializer_list<cm::string_view> views) +{ + std::size_t total_size = 0; + for (cm::string_view const& view : views) { + total_size += view.size(); + } + + std::string result(total_size, '\0'); + std::string::iterator sit = result.begin(); + for (cm::string_view const& view : views) { + sit = std::copy_n(view.data(), view.size(), sit); + } + return result; +} + +bool cmIsInternallyOn(cm::string_view val) +{ + return (val.size() == 4) && // + (val[0] == 'I' || val[0] == 'i') && // + (val[1] == '_') && // + (val[2] == 'O' || val[2] == 'o') && // + (val[3] == 'N' || val[3] == 'n'); +} + +bool cmIsNOTFOUND(cm::string_view val) +{ + return (val == "NOTFOUND") || cmHasLiteralSuffix(val, "-NOTFOUND"); +} + +bool cmIsOn(cm::string_view val) +{ + switch (val.size()) { + case 1: + return val[0] == '1' || val[0] == 'Y' || val[0] == 'y'; + case 2: + return // + (val[0] == 'O' || val[0] == 'o') && // + (val[1] == 'N' || val[1] == 'n'); + case 3: + return // + (val[0] == 'Y' || val[0] == 'y') && // + (val[1] == 'E' || val[1] == 'e') && // + (val[2] == 'S' || val[2] == 's'); + case 4: + return // + (val[0] == 'T' || val[0] == 't') && // + (val[1] == 'R' || val[1] == 'r') && // + (val[2] == 'U' || val[2] == 'u') && // + (val[3] == 'E' || val[3] == 'e'); + default: + break; + } + + return false; +} + +bool cmIsOff(cm::string_view val) +{ + switch (val.size()) { + case 0: + return true; + case 1: + return val[0] == '0' || val[0] == 'N' || val[0] == 'n'; + case 2: + return // + (val[0] == 'N' || val[0] == 'n') && // + (val[1] == 'O' || val[1] == 'o'); + case 3: + return // + (val[0] == 'O' || val[0] == 'o') && // + (val[1] == 'F' || val[1] == 'f') && // + (val[2] == 'F' || val[2] == 'f'); + case 5: + return // + (val[0] == 'F' || val[0] == 'f') && // + (val[1] == 'A' || val[1] == 'a') && // + (val[2] == 'L' || val[2] == 'l') && // + (val[3] == 'S' || val[3] == 's') && // + (val[4] == 'E' || val[4] == 'e'); + case 6: + return // + (val[0] == 'I' || val[0] == 'i') && // + (val[1] == 'G' || val[1] == 'g') && // + (val[2] == 'N' || val[2] == 'n') && // + (val[3] == 'O' || val[3] == 'o') && // + (val[4] == 'R' || val[4] == 'r') && // + (val[5] == 'E' || val[5] == 'e'); + default: + break; + } + + return cmIsNOTFOUND(val); +} + +bool cmStrToLong(const char* str, long* value) +{ + errno = 0; + char* endp; + *value = strtol(str, &endp, 10); + return (*endp == '\0') && (endp != str) && (errno == 0); +} + +bool cmStrToLong(std::string const& str, long* value) +{ + return cmStrToLong(str.c_str(), value); +} + +bool cmStrToULong(const char* str, unsigned long* value) +{ + errno = 0; + char* endp; + while (cmIsSpace(*str)) { + ++str; + } + if (*str == '-') { + return false; + } + *value = strtoul(str, &endp, 10); + return (*endp == '\0') && (endp != str) && (errno == 0); +} + +bool cmStrToULong(std::string const& str, unsigned long* value) +{ + return cmStrToULong(str.c_str(), value); +} diff --git a/Source/cmStringAlgorithms.h b/Source/cmStringAlgorithms.h new file mode 100644 index 0000000..5b8b878 --- /dev/null +++ b/Source/cmStringAlgorithms.h @@ -0,0 +1,292 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#ifndef cmStringAlgorithms_h +#define cmStringAlgorithms_h + +#include "cmConfigure.h" // IWYU pragma: keep + +#include "cmRange.h" +#include "cm_string_view.hxx" +#include <cctype> +#include <initializer_list> +#include <sstream> +#include <string.h> +#include <string> +#include <utility> +#include <vector> + +/** String range type. */ +typedef cmRange<std::vector<std::string>::const_iterator> cmStringRange; + +/** Callable string comparison struct. */ +struct cmStrCmp +{ + cmStrCmp(std::string str) + : Test_(std::move(str)) + { + } + + bool operator()(cm::string_view sv) const { return Test_ == sv; } + +private: + std::string const Test_; +}; + +/** Returns true if the character @a ch is a whitespace character. **/ +inline bool cmIsSpace(char ch) +{ + return ((ch & 0x80) == 0) && std::isspace(ch); +} + +/** Returns a string that has whitespace removed from the start and the end. */ +std::string cmTrimWhitespace(cm::string_view str); + +/** Returns a string that has quotes removed from the start and the end. */ +std::string cmRemoveQuotes(cm::string_view str); + +/** Escape quotes in a string. */ +std::string cmEscapeQuotes(cm::string_view str); + +/** Joins elements of a range with separator into a single string. */ +template <typename Range> +std::string cmJoin(Range const& rng, cm::string_view separator) +{ + if (rng.empty()) { + return std::string(); + } + + std::ostringstream os; + auto it = rng.begin(); + auto const end = rng.end(); + os << *it; + while (++it != end) { + os << separator << *it; + } + return os.str(); +} + +/** Extract tokens that are separated by any of the characters in @a sep. */ +std::vector<std::string> cmTokenize(cm::string_view str, cm::string_view sep); + +/** + * Expand the ; separated string @a arg into multiple arguments. + * All found arguments are appended to @a argsOut. + */ +void cmExpandList(cm::string_view arg, std::vector<std::string>& argsOut, + bool emptyArgs = false); + +/** + * Expand out any arguments in the string range [@a first, @a last) that have + * ; separated strings into multiple arguments. All found arguments are + * appended to @a argsOut. + */ +template <class InputIt> +void cmExpandLists(InputIt first, InputIt last, + std::vector<std::string>& argsOut) +{ + for (; first != last; ++first) { + ExpandList(*first, argsOut); + } +} + +/** + * Same as cmExpandList but a new vector is created containing + * the expanded arguments from the string @a arg. + */ +std::vector<std::string> cmExpandedList(cm::string_view arg, + bool emptyArgs = false); + +/** + * Same as cmExpandList but a new vector is created containing the expanded + * versions of all arguments in the string range [@a first, @a last). + */ +template <class InputIt> +std::vector<std::string> cmExpandedLists(InputIt first, InputIt last) +{ + std::vector<std::string> argsOut; + for (; first != last; ++first) { + cmExpandList(*first, argsOut); + } + return argsOut; +} + +/** Concatenate string pieces into a single string. */ +std::string cmCatViews(std::initializer_list<cm::string_view> views); + +/** Utility class for cmStrCat. */ +class cmAlphaNum +{ +public: + cmAlphaNum(cm::string_view view) + : View_(view) + { + } + cmAlphaNum(std::string const& str) + : View_(str) + { + } + cmAlphaNum(const char* str) + : View_(str) + { + } + cmAlphaNum(char ch) + : View_(Digits_, 1) + { + Digits_[0] = ch; + } + cmAlphaNum(int val); + cmAlphaNum(unsigned int val); + cmAlphaNum(long int val); + cmAlphaNum(unsigned long int val); + cmAlphaNum(long long int val); + cmAlphaNum(unsigned long long int val); + cmAlphaNum(float val); + cmAlphaNum(double val); + + cm::string_view View() const { return View_; } + +private: + cm::string_view View_; + char Digits_[32]; +}; + +/** Concatenate string pieces and numbers into a single string. */ +template <typename... AV> +inline std::string cmStrCat(cmAlphaNum const& a, cmAlphaNum const& b, + AV const&... args) +{ + return cmCatViews( + { a.View(), b.View(), static_cast<cmAlphaNum const&>(args).View()... }); +} + +/** Joins wrapped elements of a range with separator into a single string. */ +template <typename Range> +std::string cmWrap(cm::string_view prefix, Range const& rng, + cm::string_view suffix, cm::string_view sep) +{ + if (rng.empty()) { + return std::string(); + } + return cmCatViews( + { prefix, cmJoin(rng, cmCatViews({ suffix, sep, prefix })), suffix }); +} + +/** Joins wrapped elements of a range with separator into a single string. */ +template <typename Range> +std::string cmWrap(char prefix, Range const& rng, char suffix, + cm::string_view sep) +{ + return cmWrap(cm::string_view(&prefix, 1), rng, cm::string_view(&suffix, 1), + sep); +} + +/** + * Does a string indicates that CMake/CPack/CTest internally + * forced this value. This is not the same as On, but this + * may be considered as "internally switched on". + */ +bool cmIsInternallyOn(cm::string_view val); +inline bool cmIsInternallyOn(const char* val) +{ + if (!val) { + return false; + } + return cmIsInternallyOn(cm::string_view(val)); +} + +/** Return true if value is NOTFOUND or ends in -NOTFOUND. */ +bool cmIsNOTFOUND(cm::string_view val); + +/** + * Does a string indicate a true or ON value? This is not the same as ifdef. + */ +bool cmIsOn(cm::string_view val); +inline bool cmIsOn(const char* val) +{ + if (!val) { + return false; + } + return cmIsOn(cm::string_view(val)); +} + +/** + * Does a string indicate a false or off value ? Note that this is + * not the same as !IsOn(...) because there are a number of + * ambiguous values such as "/usr/local/bin" a path will result in + * IsON and IsOff both returning false. Note that the special path + * NOTFOUND, *-NOTFOUND or IGNORE will cause IsOff to return true. + */ +bool cmIsOff(cm::string_view val); +inline bool cmIsOff(const char* val) +{ + if (!val) { + return true; + } + return cmIsOff(cm::string_view(val)); +} + +/** Returns true if string @a str starts with the character @a prefix. */ +inline bool cmHasPrefix(cm::string_view str, char prefix) +{ + return !str.empty() && (str.front() == prefix); +} + +/** Returns true if string @a str starts with string @a prefix. */ +inline bool cmHasPrefix(cm::string_view str, cm::string_view prefix) +{ + return str.compare(0, prefix.size(), prefix) == 0; +} + +/** Returns true if string @a str starts with string @a prefix. */ +template <size_t N> +inline bool cmHasLiteralPrefix(cm::string_view str, const char (&prefix)[N]) +{ + return cmHasPrefix(str, cm::string_view(prefix, N - 1)); +} + +/** Returns true if string @a str ends with the character @a suffix. */ +inline bool cmHasSuffix(cm::string_view str, char suffix) +{ + return !str.empty() && (str.back() == suffix); +} + +/** Returns true if string @a str ends with string @a suffix. */ +inline bool cmHasSuffix(cm::string_view str, cm::string_view suffix) +{ + return str.size() >= suffix.size() && + str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0; +} + +/** Returns true if string @a str ends with string @a suffix. */ +template <size_t N> +inline bool cmHasLiteralSuffix(cm::string_view str, const char (&suffix)[N]) +{ + return cmHasSuffix(str, cm::string_view(suffix, N - 1)); +} + +/** Removes an existing suffix character of from the string @a str. */ +inline void cmStripSuffixIfExists(std::string& str, char suffix) +{ + if (cmHasSuffix(str, suffix)) { + str.pop_back(); + } +} + +/** Removes an existing suffix string of from the string @a str. */ +inline void cmStripSuffixIfExists(std::string& str, cm::string_view suffix) +{ + if (cmHasSuffix(str, suffix)) { + str.resize(str.size() - suffix.size()); + } +} + +/** Converts a string to long. Expects that the whole string is an integer. */ +bool cmStrToLong(const char* str, long* value); +bool cmStrToLong(std::string const& str, long* value); + +/** Converts a string to unsigned long. Expects that the whole string is an + * integer */ +bool cmStrToULong(const char* str, unsigned long* value); +bool cmStrToULong(std::string const& str, unsigned long* value); + +#endif diff --git a/Source/cmStringCommand.cxx b/Source/cmStringCommand.cxx index 998f904..9a2de9d 100644 --- a/Source/cmStringCommand.cxx +++ b/Source/cmStringCommand.cxx @@ -8,139 +8,70 @@ #include <algorithm> #include <ctype.h> #include <iterator> -#include <memory> // IWYU pragma: keep +#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_BUILD_WITH_CMAKE) +#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].c_str())); + std::unique_ptr<cmCryptoHash> hash(cmCryptoHash::New(args[0])); if (hash) { std::string out = hash->HashString(args[2]); - this->Makefile->AddDefinition(args[1], out.c_str()); + 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.c_str()); + 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.c_str()); + 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.c_str()); + 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.c_str()); + 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.c_str()); + 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.c_str()); + 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().c_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.c_str()); + 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,25 +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).c_str()); + 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; } @@ -558,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; } @@ -577,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.c_str()); + 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; } @@ -602,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.c_str()); + 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.c_str()); + 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).c_str()); + 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; } @@ -673,14 +625,15 @@ bool cmStringCommand::HandleGenexStripCommand( const std::string& variableName = args[2]; - this->Makefile->AddDefinition(variableName, result.c_str()); + 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; } @@ -712,13 +665,16 @@ bool cmStringCommand::HandleStripCommand(std::vector<std::string> const& args) outLength = endPos - startPos + 1; } - this->Makefile->AddDefinition( - variableName, stringValue.substr(startPos, outLength).c_str()); + 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 { @@ -730,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 (!cmSystemTools::StringToULong(args[ArgPos::TIMES].c_str(), ×)) { - this->Makefile->IssueMessage(MessageType::FATAL_ERROR, - "repeat count is not a positive number."); + if (!cmStrToULong(args[ArgPos::TIMES], ×)) { + makefile.IssueMessage(MessageType::FATAL_ERROR, + "repeat count is not a positive number."); return true; } @@ -766,14 +721,15 @@ bool cmStringCommand::HandleRepeatCommand(std::vector<std::string> const& args) break; } - this->Makefile->AddDefinition(variableName, result.c_str()); + 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; } @@ -810,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(); @@ -833,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; } @@ -865,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.c_str()); + 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_BUILD_WITH_CMAKE) +#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; } @@ -898,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++]; @@ -922,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; } } @@ -932,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; } @@ -942,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; } @@ -955,12 +912,59 @@ bool cmStringCommand::HandleUuidCommand(std::vector<std::string> const& args) uuid = cmSystemTools::UpperCase(uuid); } - this->Makefile->AddDefinition(outputVariable, uuid.c_str()); + 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 acde605..bd71ba2 100644 --- a/Source/cmStringCommand.h +++ b/Source/cmStringCommand.h @@ -5,62 +5,16 @@ #include "cmConfigure.h" // IWYU pragma: keep -#include <cstddef> #include <string> #include <vector> -#include "cmCommand.h" - class cmExecutionStatus; -/** \class cmStringCommand +/** * \brief Common string operations * */ -class cmStringCommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - cmCommand* Clone() override { return new 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/cmSubcommandTable.cxx b/Source/cmSubcommandTable.cxx new file mode 100644 index 0000000..f6194f8 --- /dev/null +++ b/Source/cmSubcommandTable.cxx @@ -0,0 +1,31 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#include "cmSubcommandTable.h" + +#include <algorithm> + +#include "cmExecutionStatus.h" +#include "cmStringAlgorithms.h" + +cmSubcommandTable::cmSubcommandTable(std::initializer_list<InitElem> init) + : Impl(init.begin(), init.end()) +{ + std::sort(this->Impl.begin(), this->Impl.end(), + [](Elem const& left, Elem const& right) { + return left.first < right.first; + }); +} + +bool cmSubcommandTable::operator()(cm::string_view key, + std::vector<std::string> const& args, + cmExecutionStatus& status) const +{ + auto const it = std::lower_bound( + this->Impl.begin(), this->Impl.end(), key, + [](Elem const& elem, cm::string_view k) { return elem.first < k; }); + if (it != this->Impl.end() && it->first == key) { + return it->second(args, status); + } + status.SetError(cmStrCat("does not recognize sub-command ", key)); + return false; +} diff --git a/Source/cmSubcommandTable.h b/Source/cmSubcommandTable.h new file mode 100644 index 0000000..21342bb --- /dev/null +++ b/Source/cmSubcommandTable.h @@ -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. */ +#ifndef cmSubcommandTable_h +#define cmSubcommandTable_h + +#include "cmConfigure.h" // IWYU pragma: keep + +#include "cm_static_string_view.hxx" +#include "cm_string_view.hxx" + +#include <initializer_list> +#include <string> +#include <utility> +#include <vector> + +class cmExecutionStatus; + +class cmSubcommandTable +{ +public: + using Command = bool (*)(std::vector<std::string> const&, + cmExecutionStatus&); + + using Elem = std::pair<cm::string_view, Command>; + using InitElem = std::pair<cm::static_string_view, Command>; + + cmSubcommandTable(std::initializer_list<InitElem> init); + + bool operator()(cm::string_view key, std::vector<std::string> const& args, + cmExecutionStatus& status) const; + +private: + std::vector<Elem> Impl; +}; + +#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/cmSubdirCommand.h b/Source/cmSubdirCommand.h index adab757..3499c46 100644 --- a/Source/cmSubdirCommand.h +++ b/Source/cmSubdirCommand.h @@ -8,6 +8,8 @@ #include <string> #include <vector> +#include "cm_memory.hxx" + #include "cmCommand.h" class cmExecutionStatus; @@ -25,7 +27,10 @@ public: /** * This is a virtual constructor for the command. */ - cmCommand* Clone() override { return new cmSubdirCommand; } + std::unique_ptr<cmCommand> Clone() override + { + return cm::make_unique<cmSubdirCommand>(); + } /** * This is called when the command is first encountered in diff --git a/Source/cmSubdirDependsCommand.h b/Source/cmSubdirDependsCommand.h index 2db28c6..64c28b9 100644 --- a/Source/cmSubdirDependsCommand.h +++ b/Source/cmSubdirDependsCommand.h @@ -8,6 +8,8 @@ #include <string> #include <vector> +#include "cm_memory.hxx" + #include "cmCommand.h" class cmExecutionStatus; @@ -15,7 +17,10 @@ class cmExecutionStatus; class cmSubdirDependsCommand : public cmCommand { public: - cmCommand* Clone() override { return new cmSubdirDependsCommand; } + std::unique_ptr<cmCommand> Clone() override + { + return cm::make_unique<cmSubdirDependsCommand>(); + } bool InitialPass(std::vector<std::string> const& args, cmExecutionStatus& status) override; }; diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx index 1501481..b7287d9 100644 --- a/Source/cmSystemTools.cxx +++ b/Source/cmSystemTools.cxx @@ -6,9 +6,10 @@ #include "cmDuration.h" #include "cmProcessOutput.h" #include "cmRange.h" +#include "cmStringAlgorithms.h" #include "cm_uv.h" -#if defined(CMAKE_BUILD_WITH_CMAKE) +#if !defined(CMAKE_BOOTSTRAP) # include "cmArchiveWrite.h" # include "cmLocale.h" # include "cm_libarchive.h" @@ -20,7 +21,7 @@ # endif #endif -#if defined(CMAKE_BUILD_WITH_CMAKE) +#if !defined(CMAKE_BOOTSTRAP) # include "cmCryptoHash.h" #endif @@ -83,11 +84,6 @@ cmSystemTools::OutputCallback s_StdoutCallback; } // namespace -static bool cm_isspace(char c) -{ - return ((c & 0x80) == 0) && isspace(c); -} - #if !defined(HAVE_ENVIRON_NOT_REQUIRE_PROTOTYPE) // For GetEnvironmentVariables # if defined(_WIN32) @@ -97,7 +93,7 @@ extern char** environ; # endif #endif -#if defined(CMAKE_BUILD_WITH_CMAKE) +#if !defined(CMAKE_BOOTSTRAP) static std::string cm_archive_entry_pathname(struct archive_entry* entry) { # if cmsys_STL_HAS_WSTRING @@ -151,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"); } } @@ -169,49 +163,20 @@ 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"); } } #endif -std::string cmSystemTools::EscapeQuotes(const std::string& str) -{ - std::string result; - result.reserve(str.size()); - for (const char* ch = str.c_str(); *ch != '\0'; ++ch) { - if (*ch == '"') { - result += '\\'; - } - result += *ch; - } - return result; -} - -std::string cmSystemTools::HelpFileName(std::string name) +std::string cmSystemTools::HelpFileName(cm::string_view str) { + std::string name(str); cmSystemTools::ReplaceString(name, "<", ""); cmSystemTools::ReplaceString(name, ">", ""); return name; } -std::string cmSystemTools::TrimWhitespace(const std::string& s) -{ - std::string::const_iterator start = s.begin(); - while (start != s.end() && cm_isspace(*start)) { - ++start; - } - if (start == s.end()) { - return ""; - } - std::string::const_iterator stop = s.end() - 1; - while (cm_isspace(*stop)) { - --stop; - } - return std::string(start, stop + 1); -} - void cmSystemTools::Error(const std::string& m) { std::string message = "CMake Error: " + m; @@ -276,121 +241,11 @@ 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); } -bool cmSystemTools::IsInternallyOn(const char* val) -{ - if (!val) { - return false; - } - std::string v = val; - if (v.size() > 4) { - return false; - } - - for (char& c : v) { - c = static_cast<char>(toupper(c)); - } - return v == "I_ON"; -} - -bool cmSystemTools::IsOn(const char* val) -{ - if (!val) { - return false; - } - /* clang-format off */ - // "1" - if (val[0] == '1' && val[1] == '\0') { - return true; - } - // "ON" - if ((val[0] == 'O' || val[0] == 'o') && - (val[1] == 'N' || val[1] == 'n') && val[2] == '\0') { - return true; - } - // "Y", "YES" - if ((val[0] == 'Y' || val[0] == 'y') && (val[1] == '\0' || ( - (val[1] == 'E' || val[1] == 'e') && - (val[2] == 'S' || val[2] == 's') && val[3] == '\0'))) { - return true; - } - // "TRUE" - if ((val[0] == 'T' || val[0] == 't') && - (val[1] == 'R' || val[1] == 'r') && - (val[2] == 'U' || val[2] == 'u') && - (val[3] == 'E' || val[3] == 'e') && val[4] == '\0') { - return true; - } - /* clang-format on */ - return false; -} - -bool cmSystemTools::IsOn(const std::string& val) -{ - return cmSystemTools::IsOn(val.c_str()); -} - -bool cmSystemTools::IsNOTFOUND(const char* val) -{ - if (strcmp(val, "NOTFOUND") == 0) { - return true; - } - return cmHasLiteralSuffix(val, "-NOTFOUND"); -} - -bool cmSystemTools::IsOff(const char* val) -{ - // "" - if (!val || val[0] == '\0') { - return true; - } - /* clang-format off */ - // "0" - if (val[0] == '0' && val[1] == '\0') { - return true; - } - // "OFF" - if ((val[0] == 'O' || val[0] == 'o') && - (val[1] == 'F' || val[1] == 'f') && - (val[2] == 'F' || val[2] == 'f') && val[3] == '\0') { - return true; - } - // "N", "NO" - if ((val[0] == 'N' || val[0] == 'n') && (val[1] == '\0' || ( - (val[1] == 'O' || val[1] == 'o') && val[2] == '\0'))) { - return true; - } - // "FALSE" - if ((val[0] == 'F' || val[0] == 'f') && - (val[1] == 'A' || val[1] == 'a') && - (val[2] == 'L' || val[2] == 'l') && - (val[3] == 'S' || val[3] == 's') && - (val[4] == 'E' || val[4] == 'e') && val[5] == '\0') { - return true; - } - // "IGNORE" - if ((val[0] == 'I' || val[0] == 'i') && - (val[1] == 'G' || val[1] == 'g') && - (val[2] == 'N' || val[2] == 'n') && - (val[3] == 'O' || val[3] == 'o') && - (val[4] == 'R' || val[4] == 'r') && - (val[5] == 'E' || val[5] == 'e') && val[6] == '\0') { - return true; - } - /* clang-format on */ - return cmSystemTools::IsNOTFOUND(val); -} - -bool cmSystemTools::IsOff(const std::string& val) -{ - return cmSystemTools::IsOff(val.c_str()); -} - void cmSystemTools::ParseWindowsCommandLine(const char* command, std::vector<std::string>& args) { @@ -424,7 +279,7 @@ void cmSystemTools::ParseWindowsCommandLine(const char* command, } else { arg.append(backslashes, '\\'); backslashes = 0; - if (cm_isspace(*c)) { + if (cmIsSpace(*c)) { if (in_quotes) { arg.append(1, *c); } else if (in_argument) { @@ -487,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; @@ -843,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; } @@ -863,7 +715,7 @@ std::string cmSystemTools::FileExistsInParentDirectories( cmSystemTools::ConvertToUnixSlashes(dir); std::string prevDir; while (dir != prevDir) { - std::string path = dir + "/" + file; + std::string path = cmStrCat(dir, "/", file); if (cmSystemTools::FileExists(path)) { return path; } @@ -1006,7 +858,7 @@ bool cmSystemTools::RenameFile(const std::string& oldname, std::string cmSystemTools::ComputeFileHash(const std::string& source, cmCryptoHash::Algo algo) { -#if defined(CMAKE_BUILD_WITH_CMAKE) +#if !defined(CMAKE_BOOTSTRAP) cmCryptoHash hash(algo); return hash.HashFile(source); #else @@ -1019,7 +871,7 @@ std::string cmSystemTools::ComputeFileHash(const std::string& source, std::string cmSystemTools::ComputeStringMD5(const std::string& input) { -#if defined(CMAKE_BUILD_WITH_CMAKE) +#if !defined(CMAKE_BOOTSTRAP) cmCryptoHash md5(cmCryptoHash::AlgoMD5); return md5.HashString(input); #else @@ -1035,7 +887,7 @@ std::string cmSystemTools::ComputeCertificateThumbprint( { std::string thumbprint; -#if defined(CMAKE_BUILD_WITH_CMAKE) && defined(_WIN32) +#if !defined(CMAKE_BOOTSTRAP) && defined(_WIN32) BYTE* certData = NULL; CRYPT_INTEGER_BLOB cryptBlob; HCERTSTORE certStore = NULL; @@ -1139,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); @@ -1151,75 +1001,6 @@ void cmSystemTools::GlobDirs(const std::string& path, } } -void cmSystemTools::ExpandListArgument(const std::string& arg, - std::vector<std::string>& argsOut, - bool emptyArgs) -{ - // If argument is empty, it is an empty list. - if (!emptyArgs && arg.empty()) { - return; - } - // if there are no ; in the name then just copy the current string - if (arg.find(';') == std::string::npos) { - argsOut.push_back(arg); - return; - } - std::string newArg; - const char* last = arg.c_str(); - // Break the string at non-escaped semicolons not nested in []. - int squareNesting = 0; - for (const char* c = last; *c; ++c) { - switch (*c) { - case '\\': { - // We only want to allow escaping of semicolons. Other - // escapes should not be processed here. - const char* next = c + 1; - if (*next == ';') { - newArg.append(last, c - last); - // Skip over the escape character - last = c = next; - } - } break; - case '[': { - ++squareNesting; - } break; - case ']': { - --squareNesting; - } break; - case ';': { - // Break the string here if we are not nested inside square - // brackets. - if (squareNesting == 0) { - newArg.append(last, c - last); - // Skip over the semicolon - last = c + 1; - if (!newArg.empty() || emptyArgs) { - // Add the last argument if the string is not empty. - argsOut.push_back(newArg); - newArg.clear(); - } - } - } break; - default: { - // Just append this character. - } break; - } - } - newArg.append(last); - if (!newArg.empty() || emptyArgs) { - // Add the last argument if the string is not empty. - argsOut.push_back(newArg); - } -} - -std::vector<std::string> cmSystemTools::ExpandedListArgument( - const std::string& arg, bool emptyArgs) -{ - std::vector<std::string> argsOut; - ExpandListArgument(arg, argsOut, emptyArgs); - return argsOut; -} - bool cmSystemTools::SimpleGlob(const std::string& glob, std::vector<std::string>& files, int type /* = 0 */) @@ -1264,65 +1045,6 @@ bool cmSystemTools::SimpleGlob(const std::string& glob, return res; } -cmSystemTools::FileFormat cmSystemTools::GetFileFormat(std::string const& ext) -{ - if (ext.empty()) { - return cmSystemTools::NO_FILE_FORMAT; - } - if (ext == "c" || ext == ".c" || ext == "m" || ext == ".m") { - return cmSystemTools::C_FILE_FORMAT; - } - if (ext == "C" || ext == ".C" || ext == "M" || ext == ".M" || ext == "c++" || - ext == ".c++" || ext == "cc" || ext == ".cc" || ext == "cpp" || - ext == ".cpp" || ext == "cxx" || ext == ".cxx" || ext == "mm" || - ext == ".mm") { - return cmSystemTools::CXX_FILE_FORMAT; - } - if (ext == "f" || ext == ".f" || ext == "F" || ext == ".F" || ext == "f77" || - ext == ".f77" || ext == "f90" || ext == ".f90" || ext == "for" || - ext == ".for" || ext == "f95" || ext == ".f95") { - return cmSystemTools::FORTRAN_FILE_FORMAT; - } - if (ext == "java" || ext == ".java") { - return cmSystemTools::JAVA_FILE_FORMAT; - } - if (ext == "cu" || ext == ".cu") { - return cmSystemTools::CUDA_FILE_FORMAT; - } - if (ext == "H" || ext == ".H" || ext == "h" || ext == ".h" || ext == "h++" || - ext == ".h++" || ext == "hm" || ext == ".hm" || ext == "hpp" || - ext == ".hpp" || ext == "hxx" || ext == ".hxx" || ext == "in" || - ext == ".in" || ext == "txx" || ext == ".txx") { - return cmSystemTools::HEADER_FILE_FORMAT; - } - if (ext == "rc" || ext == ".rc") { - return cmSystemTools::RESOURCE_FILE_FORMAT; - } - if (ext == "def" || ext == ".def") { - return cmSystemTools::DEFINITION_FILE_FORMAT; - } - if (ext == "lib" || ext == ".lib" || ext == "a" || ext == ".a") { - return cmSystemTools::STATIC_LIBRARY_FILE_FORMAT; - } - if (ext == "o" || ext == ".o" || ext == "obj" || ext == ".obj") { - return cmSystemTools::OBJECT_FILE_FORMAT; - } -#ifdef __APPLE__ - if (ext == "dylib" || ext == ".dylib") { - return cmSystemTools::SHARED_LIBRARY_FILE_FORMAT; - } - if (ext == "so" || ext == ".so" || ext == "bundle" || ext == ".bundle") { - return cmSystemTools::MODULE_FILE_FORMAT; - } -#else // __APPLE__ - if (ext == "so" || ext == ".so" || ext == "sl" || ext == ".sl" || - ext == "dll" || ext == ".dll") { - return cmSystemTools::SHARED_LIBRARY_FILE_FORMAT; - } -#endif // __APPLE__ - return cmSystemTools::UNKNOWN_FILE_FORMAT; -} - std::string cmSystemTools::ConvertToOutputPath(std::string const& path) { #if defined(_WIN32) && !defined(__CYGWIN__) @@ -1448,12 +1170,11 @@ std::string cmSystemTools::ForceToRelativePath(std::string const& local_path, return relative; } -#ifdef CMAKE_BUILD_WITH_CMAKE +#ifndef CMAKE_BOOTSTRAP 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); @@ -1513,7 +1234,7 @@ void cmSystemTools::EnableVSConsoleOutput() // output and allow it to be captured on the fly. cmSystemTools::PutEnv("vsconsoleoutput=1"); -# ifdef CMAKE_BUILD_WITH_CMAKE +# ifndef CMAKE_BOOTSTRAP // VS sets an environment variable to tell MS tools like "cl" to report // output through a backdoor pipe instead of stdout/stderr. Unset the // environment variable to close this backdoor for any path of process @@ -1535,14 +1256,12 @@ bool cmSystemTools::CreateTar(const std::string& outFileName, std::string const& mtime, std::string const& format) { -#if defined(CMAKE_BUILD_WITH_CMAKE) +#if !defined(CMAKE_BOOTSTRAP) 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; } @@ -1589,7 +1308,7 @@ bool cmSystemTools::CreateTar(const std::string& outFileName, #endif } -#if defined(CMAKE_BUILD_WITH_CMAKE) +#if !defined(CMAKE_BOOTSTRAP) namespace { # define BSDTAR_FILESIZE_PRINTF "%lu" # define BSDTAR_FILESIZE_TYPE unsigned long @@ -1885,7 +1604,7 @@ bool cmSystemTools::ExtractTar(const std::string& outFileName, const std::vector<std::string>& files, bool verbose) { -#if defined(CMAKE_BUILD_WITH_CMAKE) +#if !defined(CMAKE_BOOTSTRAP) return extract_tar(outFileName, files, verbose, true); #else (void)outFileName; @@ -1899,7 +1618,7 @@ bool cmSystemTools::ListTar(const std::string& outFileName, const std::vector<std::string>& files, bool verbose) { -#if defined(CMAKE_BUILD_WITH_CMAKE) +#if !defined(CMAKE_BOOTSTRAP) return extract_tar(outFileName, files, verbose, false); #else (void)outFileName; @@ -2225,40 +1944,34 @@ void cmSystemTools::FindCMakeResources(const char* argv0) } #endif exe_dir = cmSystemTools::GetActualCaseForPath(exe_dir); - cmSystemToolsCMakeCommand = exe_dir; - cmSystemToolsCMakeCommand += "/cmake"; - cmSystemToolsCMakeCommand += cmSystemTools::GetExecutableExtension(); -#ifndef CMAKE_BUILD_WITH_CMAKE + 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(); } -#ifdef CMAKE_BUILD_WITH_CMAKE +#ifndef CMAKE_BOOTSTRAP // Install tree has // - "<prefix><CMAKE_BIN_DIR>/cmake" // - "<prefix><CMAKE_DATA_DIR>" @@ -2456,7 +2169,8 @@ struct cmSystemToolsRPathInfo #if defined(CMAKE_USE_ELF_PARSER) bool cmSystemTools::ChangeRPath(std::string const& file, std::string const& oldRPath, - std::string const& newRPath, std::string* emsg, + std::string const& newRPath, + bool removeEnvironmentRPath, std::string* emsg, bool* changed) { if (changed) { @@ -2490,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; } @@ -2543,7 +2258,9 @@ bool cmSystemTools::ChangeRPath(std::string const& file, // Construct the new value which preserves the part of the path // not being changed. - rp[rp_count].Value = se[i]->Value.substr(0, prefix_len); + if (!removeEnvironmentRPath) { + rp[rp_count].Value = se[i]->Value.substr(0, prefix_len); + } rp[rp_count].Value += newRPath; rp[rp_count].Value += se[i]->Value.substr(pos + oldRPath.length()); @@ -2555,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; } @@ -2593,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; } @@ -2610,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; } @@ -2629,6 +2342,7 @@ bool cmSystemTools::ChangeRPath(std::string const& file, bool cmSystemTools::ChangeRPath(std::string const& /*file*/, std::string const& /*oldRPath*/, std::string const& /*newRPath*/, + bool /*removeEnvironmentRPath*/, std::string* /*emsg*/, bool* /*changed*/) { return false; @@ -2640,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'))) { @@ -2951,61 +2666,20 @@ bool cmSystemTools::CheckRPath(std::string const& file, bool cmSystemTools::RepeatedRemoveDirectory(const std::string& dir) { +#ifdef _WIN32 // Windows sometimes locks files temporarily so try a few times. - for (int i = 0; i < 10; ++i) { + WindowsFileRetry retry = cmSystemTools::GetWindowsFileRetry(); + + for (unsigned int i = 0; i < retry.Count; ++i) { if (cmSystemTools::RemoveADirectory(dir)) { return true; } - cmSystemTools::Delay(100); + cmSystemTools::Delay(retry.Delay); } return false; -} - -std::vector<std::string> cmSystemTools::tokenize(const std::string& str, - const std::string& sep) -{ - std::vector<std::string> tokens; - std::string::size_type tokend = 0; - - do { - std::string::size_type tokstart = str.find_first_not_of(sep, tokend); - if (tokstart == std::string::npos) { - break; // no more tokens - } - tokend = str.find_first_of(sep, tokstart); - if (tokend == std::string::npos) { - tokens.push_back(str.substr(tokstart)); - } else { - tokens.push_back(str.substr(tokstart, tokend - tokstart)); - } - } while (tokend != std::string::npos); - - if (tokens.empty()) { - tokens.emplace_back(); - } - return tokens; -} - -bool cmSystemTools::StringToLong(const char* str, long* value) -{ - errno = 0; - char* endp; - *value = strtol(str, &endp, 10); - return (*endp == '\0') && (endp != str) && (errno == 0); -} - -bool cmSystemTools::StringToULong(const char* str, unsigned long* value) -{ - errno = 0; - char* endp; - while (isspace(*str)) { - ++str; - } - if (*str == '-') { - return false; - } - *value = strtoul(str, &endp, 10); - return (*endp == '\0') && (endp != str) && (errno == 0); +#else + return cmSystemTools::RemoveADirectory(dir); +#endif } std::string cmSystemTools::EncodeURL(std::string const& in, bool escapeSlashes) diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h index 016c266..953a358 100644 --- a/Source/cmSystemTools.h +++ b/Source/cmSystemTools.h @@ -8,6 +8,7 @@ #include "cmCryptoHash.h" #include "cmDuration.h" #include "cmProcessOutput.h" +#include "cm_string_view.hxx" #include "cmsys/Process.h" #include "cmsys/SystemTools.hxx" // IWYU pragma: export #include <functional> @@ -28,64 +29,13 @@ public: typedef cmProcessOutput::Encoding Encoding; /** - * Expand the ; separated string @a arg into multiple arguments. - * All found arguments are appended to @a argsOut. - */ - static void ExpandListArgument(const std::string& arg, - std::vector<std::string>& argsOut, - bool emptyArgs = false); - - /** - * Expand out any arguments in the string range [@a first, @a last) that have - * ; separated strings into multiple arguments. All found arguments are - * appended to @a argsOut. - */ - template <class InputIt> - static void ExpandLists(InputIt first, InputIt last, - std::vector<std::string>& argsOut) - { - for (; first != last; ++first) { - cmSystemTools::ExpandListArgument(*first, argsOut); - } - } - - /** - * Same as ExpandListArgument but a new vector is created containing - * the expanded arguments from the string @a arg. - */ - static std::vector<std::string> ExpandedListArgument(const std::string& arg, - bool emptyArgs = false); - - /** - * Same as ExpandList but a new vector is created containing the expanded - * versions of all arguments in the string range [@a first, @a last). - */ - template <class InputIt> - static std::vector<std::string> ExpandedLists(InputIt first, InputIt last) - { - std::vector<std::string> argsOut; - for (; first != last; ++first) { - cmSystemTools::ExpandListArgument(*first, argsOut); - } - return argsOut; - } - - /** * Look for and replace registry values in a string */ static void ExpandRegistryValues(std::string& source, KeyWOW64 view = KeyWOW64_Default); - //! Escape quotes in a string. - static std::string EscapeQuotes(const std::string& str); - /** Map help document name to file name. */ - static std::string HelpFileName(std::string); - - /** - * Returns a string that has whitespace removed from the start and the end. - */ - static std::string TrimWhitespace(const std::string& s); + static std::string HelpFileName(cm::string_view); using MessageCallback = std::function<void(const std::string&, const char*)>; /** @@ -144,31 +94,6 @@ public: cmSystemTools::s_ErrorOccured = false; } - /** - * Does a string indicates that CMake/CPack/CTest internally - * forced this value. This is not the same as On, but this - * may be considered as "internally switched on". - */ - static bool IsInternallyOn(const char* val); - /** - * does a string indicate a true or on value ? This is not the same - * as ifdef. - */ - static bool IsOn(const char* val); - static bool IsOn(const std::string& val); - - /** - * does a string indicate a false or off value ? Note that this is - * not the same as !IsOn(...) because there are a number of - * ambiguous values such as "/usr/local/bin" a path will result in - * IsON and IsOff both returning false. Note that the special path - * NOTFOUND, *-NOTFOUND or IGNORE will cause IsOff to return true. - */ - static bool IsOff(const char* val); - static bool IsOff(const std::string& val); - - //! Return true if value is NOTFOUND or ends in -NOTFOUND. - static bool IsNOTFOUND(const char* value); //! Return true if the path is a framework static bool IsPathToFramework(const std::string& value); @@ -299,27 +224,6 @@ public: static void EnableRunCommandOutput() { s_DisableRunCommandOutput = false; } static bool GetRunCommandOutput() { return s_DisableRunCommandOutput; } - /** - * Some constants for different file formats. - */ - enum FileFormat - { - NO_FILE_FORMAT = 0, - C_FILE_FORMAT, - CXX_FILE_FORMAT, - FORTRAN_FILE_FORMAT, - JAVA_FILE_FORMAT, - CUDA_FILE_FORMAT, - HEADER_FILE_FORMAT, - RESOURCE_FILE_FORMAT, - DEFINITION_FILE_FORMAT, - STATIC_LIBRARY_FILE_FORMAT, - SHARED_LIBRARY_FILE_FORMAT, - MODULE_FILE_FORMAT, - OBJECT_FILE_FORMAT, - UNKNOWN_FILE_FORMAT - }; - enum CompareOp { OP_EQUAL = 1, @@ -350,11 +254,6 @@ public: */ static int strverscmp(std::string const& lhs, std::string const& rhs); - /** - * Determine the file type based on the extension - */ - static FileFormat GetFileFormat(std::string const& ext); - /** Windows if this is true, the CreateProcess in RunCommand will * not show new console windows when running programs. */ @@ -401,7 +300,7 @@ public: static std::string ForceToRelativePath(std::string const& local_path, std::string const& remote_path); -#ifdef CMAKE_BUILD_WITH_CMAKE +#ifndef CMAKE_BOOTSTRAP /** Remove an environment variable */ static bool UnsetEnv(const char* value); @@ -499,6 +398,7 @@ public: /** Try to set the RPATH in an ELF binary. */ static bool ChangeRPath(std::string const& file, std::string const& oldRPath, std::string const& newRPath, + bool removeEnvironmentRPath, std::string* emsg = nullptr, bool* changed = nullptr); @@ -513,14 +413,6 @@ public: /** Remove a directory; repeat a few times in case of locked files. */ static bool RepeatedRemoveDirectory(const std::string& dir); - /** Tokenize a string */ - static std::vector<std::string> tokenize(const std::string& str, - const std::string& sep); - - /** Convert string to long. Expected that the whole string is an integer */ - static bool StringToLong(const char* str, long* value); - static bool StringToULong(const char* str, unsigned long* value); - /** Encode a string as a URL. */ static std::string EncodeURL(std::string const& in, bool escapeSlashes = true); diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index a67122c..5311d38 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -12,6 +12,8 @@ #include <string.h> #include <unordered_set> +#include "cm_memory.hxx" + #include "cmAlgorithms.h" #include "cmCustomCommand.h" #include "cmGeneratorExpression.h" @@ -86,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; - cmSystemTools::ExpandListArgument(entry, files); + std::vector<std::string> files = cmExpandedList(entry); for (std::string const& file : files) { if (cmHasLiteralPrefix(file, "$<TARGET_OBJECTS:") && file.back() == '>') { @@ -168,7 +169,8 @@ public: cmPropertyMap Properties; bool IsGeneratorProvided; bool HaveInstallRule; - bool DLLPlatform; + bool IsDLLPlatform; + bool IsAIX; bool IsAndroid; bool IsImportedTarget; bool ImportedGloballyVisible; @@ -217,7 +219,8 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type, impl->Name = name; impl->IsGeneratorProvided = false; impl->HaveInstallRule = false; - impl->DLLPlatform = false; + impl->IsDLLPlatform = false; + impl->IsAIX = false; impl->IsAndroid = false; impl->IsImportedTarget = (vis == VisibilityImported || vis == VisibilityImportedGlobally); @@ -225,21 +228,32 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type, impl->BuildInterfaceIncludesAppended = false; // Check whether this is a DLL platform. - impl->DLLPlatform = + impl->IsDLLPlatform = !impl->Makefile->GetSafeDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX").empty(); + // Check whether we are targeting AIX. + impl->IsAIX = + (impl->Makefile->GetSafeDefinition("CMAKE_SYSTEM_NAME") == "AIX"); + // Check whether we are targeting an Android platform. impl->IsAndroid = (impl->Makefile->GetSafeDefinition("CMAKE_SYSTEM_NAME") == "Android"); - std::string gKey; - gKey.reserve(128); - gKey += "CMAKE_"; - auto InitProperty = [this, mf, &gKey](const std::string& property, - const char* default_value) { + std::string defKey; + defKey.reserve(128); + defKey += "CMAKE_"; + auto initProp = [this, mf, &defKey](const std::string& property) { // Replace everything after "CMAKE_" - gKey.replace(gKey.begin() + 6, gKey.end(), property); - if (const char* value = mf->GetDefinition(gKey)) { + defKey.replace(defKey.begin() + 6, defKey.end(), property); + if (const char* value = mf->GetDefinition(defKey)) { + this->SetProperty(property, value); + } + }; + auto initPropValue = [this, mf, &defKey](const std::string& property, + const char* default_value) { + // Replace everything after "CMAKE_" + defKey.replace(defKey.begin() + 6, defKey.end(), property); + if (const char* value = mf->GetDefinition(defKey)) { this->SetProperty(property, value); } else if (default_value) { this->SetProperty(property, default_value); @@ -249,107 +263,110 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type, // Setup default property values. if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY && this->GetType() != cmStateEnums::UTILITY) { - InitProperty("ANDROID_API", nullptr); - InitProperty("ANDROID_API_MIN", nullptr); - InitProperty("ANDROID_ARCH", nullptr); - InitProperty("ANDROID_STL_TYPE", nullptr); - InitProperty("ANDROID_SKIP_ANT_STEP", nullptr); - InitProperty("ANDROID_PROCESS_MAX", nullptr); - InitProperty("ANDROID_PROGUARD", nullptr); - InitProperty("ANDROID_PROGUARD_CONFIG_PATH", nullptr); - InitProperty("ANDROID_SECURE_PROPS_PATH", nullptr); - InitProperty("ANDROID_NATIVE_LIB_DIRECTORIES", nullptr); - InitProperty("ANDROID_NATIVE_LIB_DEPENDENCIES", nullptr); - InitProperty("ANDROID_JAVA_SOURCE_DIR", nullptr); - InitProperty("ANDROID_JAR_DIRECTORIES", nullptr); - InitProperty("ANDROID_JAR_DEPENDENCIES", nullptr); - InitProperty("ANDROID_ASSETS_DIRECTORIES", nullptr); - InitProperty("ANDROID_ANT_ADDITIONAL_OPTIONS", nullptr); - InitProperty("BUILD_RPATH", nullptr); - InitProperty("BUILD_RPATH_USE_ORIGIN", nullptr); - InitProperty("INSTALL_NAME_DIR", nullptr); - InitProperty("INSTALL_RPATH", ""); - InitProperty("INSTALL_RPATH_USE_LINK_PATH", "OFF"); - InitProperty("INTERPROCEDURAL_OPTIMIZATION", nullptr); - InitProperty("SKIP_BUILD_RPATH", "OFF"); - InitProperty("BUILD_WITH_INSTALL_RPATH", "OFF"); - InitProperty("ARCHIVE_OUTPUT_DIRECTORY", nullptr); - InitProperty("LIBRARY_OUTPUT_DIRECTORY", nullptr); - InitProperty("RUNTIME_OUTPUT_DIRECTORY", nullptr); - InitProperty("PDB_OUTPUT_DIRECTORY", nullptr); - InitProperty("COMPILE_PDB_OUTPUT_DIRECTORY", nullptr); - InitProperty("FRAMEWORK", nullptr); - InitProperty("Fortran_FORMAT", nullptr); - InitProperty("Fortran_MODULE_DIRECTORY", nullptr); - InitProperty("Fortran_COMPILER_LAUNCHER", nullptr); - InitProperty("GNUtoMS", nullptr); - InitProperty("OSX_ARCHITECTURES", nullptr); - InitProperty("IOS_INSTALL_COMBINED", nullptr); - InitProperty("AUTOMOC", nullptr); - InitProperty("AUTOUIC", nullptr); - InitProperty("AUTORCC", nullptr); - InitProperty("AUTOGEN_ORIGIN_DEPENDS", nullptr); - InitProperty("AUTOGEN_PARALLEL", nullptr); - InitProperty("AUTOMOC_COMPILER_PREDEFINES", nullptr); - InitProperty("AUTOMOC_DEPEND_FILTERS", nullptr); - InitProperty("AUTOMOC_MACRO_NAMES", nullptr); - InitProperty("AUTOMOC_MOC_OPTIONS", nullptr); - InitProperty("AUTOUIC_OPTIONS", nullptr); - InitProperty("AUTOUIC_SEARCH_PATHS", nullptr); - InitProperty("AUTORCC_OPTIONS", nullptr); - InitProperty("LINK_DEPENDS_NO_SHARED", nullptr); - InitProperty("LINK_INTERFACE_LIBRARIES", nullptr); - InitProperty("MSVC_RUNTIME_LIBRARY", nullptr); - InitProperty("WIN32_EXECUTABLE", nullptr); - InitProperty("MACOSX_BUNDLE", nullptr); - InitProperty("MACOSX_RPATH", nullptr); - InitProperty("NO_SYSTEM_FROM_IMPORTED", nullptr); - InitProperty("BUILD_WITH_INSTALL_NAME_DIR", nullptr); - InitProperty("C_CLANG_TIDY", nullptr); - InitProperty("C_COMPILER_LAUNCHER", nullptr); - InitProperty("C_CPPLINT", nullptr); - InitProperty("C_CPPCHECK", nullptr); - InitProperty("C_INCLUDE_WHAT_YOU_USE", nullptr); - InitProperty("LINK_WHAT_YOU_USE", nullptr); - InitProperty("C_STANDARD", nullptr); - InitProperty("C_STANDARD_REQUIRED", nullptr); - InitProperty("C_EXTENSIONS", nullptr); - InitProperty("CXX_CLANG_TIDY", nullptr); - InitProperty("CXX_COMPILER_LAUNCHER", nullptr); - InitProperty("CXX_CPPLINT", nullptr); - InitProperty("CXX_CPPCHECK", nullptr); - InitProperty("CXX_INCLUDE_WHAT_YOU_USE", nullptr); - InitProperty("CXX_STANDARD", nullptr); - InitProperty("CXX_STANDARD_REQUIRED", nullptr); - InitProperty("CXX_EXTENSIONS", nullptr); - InitProperty("CUDA_STANDARD", nullptr); - InitProperty("CUDA_STANDARD_REQUIRED", nullptr); - InitProperty("CUDA_EXTENSIONS", nullptr); - InitProperty("CUDA_COMPILER_LAUNCHER", nullptr); - InitProperty("CUDA_SEPARABLE_COMPILATION", nullptr); - InitProperty("LINK_SEARCH_START_STATIC", nullptr); - InitProperty("LINK_SEARCH_END_STATIC", nullptr); - InitProperty("FOLDER", nullptr); - InitProperty("Swift_MODULE_DIRECTORY", nullptr); - InitProperty("VS_JUST_MY_CODE_DEBUGGING", nullptr); + initProp("ANDROID_API"); + initProp("ANDROID_API_MIN"); + initProp("ANDROID_ARCH"); + initProp("ANDROID_STL_TYPE"); + initProp("ANDROID_SKIP_ANT_STEP"); + initProp("ANDROID_PROCESS_MAX"); + initProp("ANDROID_PROGUARD"); + initProp("ANDROID_PROGUARD_CONFIG_PATH"); + initProp("ANDROID_SECURE_PROPS_PATH"); + initProp("ANDROID_NATIVE_LIB_DIRECTORIES"); + initProp("ANDROID_NATIVE_LIB_DEPENDENCIES"); + initProp("ANDROID_JAVA_SOURCE_DIR"); + initProp("ANDROID_JAR_DIRECTORIES"); + initProp("ANDROID_JAR_DEPENDENCIES"); + initProp("ANDROID_ASSETS_DIRECTORIES"); + initProp("ANDROID_ANT_ADDITIONAL_OPTIONS"); + initProp("BUILD_RPATH"); + initProp("BUILD_RPATH_USE_ORIGIN"); + initProp("INSTALL_NAME_DIR"); + initProp("INSTALL_REMOVE_ENVIRONMENT_RPATH"); + initPropValue("INSTALL_RPATH", ""); + initPropValue("INSTALL_RPATH_USE_LINK_PATH", "OFF"); + initProp("INTERPROCEDURAL_OPTIMIZATION"); + initPropValue("SKIP_BUILD_RPATH", "OFF"); + initPropValue("BUILD_WITH_INSTALL_RPATH", "OFF"); + initProp("ARCHIVE_OUTPUT_DIRECTORY"); + initProp("LIBRARY_OUTPUT_DIRECTORY"); + initProp("RUNTIME_OUTPUT_DIRECTORY"); + initProp("PDB_OUTPUT_DIRECTORY"); + initProp("COMPILE_PDB_OUTPUT_DIRECTORY"); + initProp("FRAMEWORK"); + initProp("Fortran_FORMAT"); + initProp("Fortran_MODULE_DIRECTORY"); + initProp("Fortran_COMPILER_LAUNCHER"); + initProp("GNUtoMS"); + initProp("OSX_ARCHITECTURES"); + initProp("IOS_INSTALL_COMBINED"); + initProp("AUTOMOC"); + initProp("AUTOUIC"); + initProp("AUTORCC"); + initProp("AUTOGEN_ORIGIN_DEPENDS"); + initProp("AUTOGEN_PARALLEL"); + initProp("AUTOMOC_COMPILER_PREDEFINES"); + initProp("AUTOMOC_DEPEND_FILTERS"); + initProp("AUTOMOC_MACRO_NAMES"); + initProp("AUTOMOC_MOC_OPTIONS"); + initProp("AUTOUIC_OPTIONS"); + initProp("AUTOUIC_SEARCH_PATHS"); + initProp("AUTORCC_OPTIONS"); + initProp("LINK_DEPENDS_NO_SHARED"); + initProp("LINK_INTERFACE_LIBRARIES"); + initProp("MSVC_RUNTIME_LIBRARY"); + initProp("WIN32_EXECUTABLE"); + initProp("MACOSX_BUNDLE"); + initProp("MACOSX_RPATH"); + initProp("NO_SYSTEM_FROM_IMPORTED"); + initProp("BUILD_WITH_INSTALL_NAME_DIR"); + initProp("C_CLANG_TIDY"); + initProp("C_COMPILER_LAUNCHER"); + initProp("C_CPPLINT"); + initProp("C_CPPCHECK"); + initProp("C_INCLUDE_WHAT_YOU_USE"); + initProp("LINK_WHAT_YOU_USE"); + initProp("C_STANDARD"); + initProp("C_STANDARD_REQUIRED"); + initProp("C_EXTENSIONS"); + initProp("CXX_CLANG_TIDY"); + initProp("CXX_COMPILER_LAUNCHER"); + initProp("CXX_CPPLINT"); + initProp("CXX_CPPCHECK"); + initProp("CXX_INCLUDE_WHAT_YOU_USE"); + initProp("CXX_STANDARD"); + initProp("CXX_STANDARD_REQUIRED"); + initProp("CXX_EXTENSIONS"); + initProp("CUDA_STANDARD"); + initProp("CUDA_STANDARD_REQUIRED"); + initProp("CUDA_EXTENSIONS"); + initProp("CUDA_COMPILER_LAUNCHER"); + initProp("CUDA_SEPARABLE_COMPILATION"); + initProp("CUDA_RESOLVE_DEVICE_SYMBOLS"); + 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"); #ifdef __APPLE__ if (this->GetGlobalGenerator()->IsXcode()) { - InitProperty("XCODE_GENERATE_SCHEME", nullptr); - InitProperty("XCODE_SCHEME_ADDRESS_SANITIZER", nullptr); - InitProperty("XCODE_SCHEME_ADDRESS_SANITIZER_USE_AFTER_RETURN", nullptr); - InitProperty("XCODE_SCHEME_THREAD_SANITIZER", nullptr); - InitProperty("XCODE_SCHEME_THREAD_SANITIZER_STOP", nullptr); - InitProperty("XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER", nullptr); - InitProperty("XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER_STOP", nullptr); - InitProperty("XCODE_SCHEME_DISABLE_MAIN_THREAD_CHECKER", nullptr); - InitProperty("XCODE_SCHEME_MAIN_THREAD_CHECKER_STOP", nullptr); - InitProperty("XCODE_SCHEME_MALLOC_SCRIBBLE", nullptr); - InitProperty("XCODE_SCHEME_MALLOC_GUARD_EDGES", nullptr); - InitProperty("XCODE_SCHEME_GUARD_MALLOC", nullptr); - InitProperty("XCODE_SCHEME_ZOMBIE_OBJECTS", nullptr); - InitProperty("XCODE_SCHEME_MALLOC_STACK", nullptr); - InitProperty("XCODE_SCHEME_DYNAMIC_LINKER_API_USAGE", nullptr); - InitProperty("XCODE_SCHEME_DYNAMIC_LIBRARY_LOADS", nullptr); + initProp("XCODE_GENERATE_SCHEME"); + initProp("XCODE_SCHEME_ADDRESS_SANITIZER"); + initProp("XCODE_SCHEME_ADDRESS_SANITIZER_USE_AFTER_RETURN"); + initProp("XCODE_SCHEME_THREAD_SANITIZER"); + initProp("XCODE_SCHEME_THREAD_SANITIZER_STOP"); + initProp("XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER"); + initProp("XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER_STOP"); + initProp("XCODE_SCHEME_DISABLE_MAIN_THREAD_CHECKER"); + initProp("XCODE_SCHEME_MAIN_THREAD_CHECKER_STOP"); + initProp("XCODE_SCHEME_MALLOC_SCRIBBLE"); + initProp("XCODE_SCHEME_MALLOC_GUARD_EDGES"); + initProp("XCODE_SCHEME_GUARD_MALLOC"); + initProp("XCODE_SCHEME_ZOMBIE_OBJECTS"); + initProp("XCODE_SCHEME_MALLOC_STACK"); + initProp("XCODE_SCHEME_DYNAMIC_LINKER_API_USAGE"); + initProp("XCODE_SCHEME_DYNAMIC_LIBRARY_LOADS"); } #endif } @@ -375,9 +392,8 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type, strcmp(prop, "MAP_IMPORTED_CONFIG_") != 0) { continue; } - std::string property = prop; - property += configUpper; - InitProperty(property, nullptr); + std::string property = cmStrCat(prop, configUpper); + initProp(property); } // Initialize per-configuration name postfix property from the @@ -387,9 +403,9 @@ 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"; - InitProperty(property, nullptr); + std::string property = + cmStrCat(cmSystemTools::UpperCase(configName), "_POSTFIX"); + initProp(property); } } } @@ -428,16 +444,16 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type, if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY && this->GetType() != cmStateEnums::UTILITY) { - InitProperty("C_VISIBILITY_PRESET", nullptr); - InitProperty("CXX_VISIBILITY_PRESET", nullptr); - InitProperty("CUDA_VISIBILITY_PRESET", nullptr); - InitProperty("VISIBILITY_INLINES_HIDDEN", nullptr); + initProp("C_VISIBILITY_PRESET"); + initProp("CXX_VISIBILITY_PRESET"); + initProp("CUDA_VISIBILITY_PRESET"); + initProp("VISIBILITY_INLINES_HIDDEN"); } if (impl->TargetType == cmStateEnums::EXECUTABLE) { - InitProperty("ANDROID_GUI", nullptr); - InitProperty("CROSSCOMPILING_EMULATOR", nullptr); - InitProperty("ENABLE_EXPORTS", nullptr); + initProp("ANDROID_GUI"); + initProp("CROSSCOMPILING_EMULATOR"); + initProp("ENABLE_EXPORTS"); } if (impl->TargetType == cmStateEnums::SHARED_LIBRARY || impl->TargetType == cmStateEnums::MODULE_LIBRARY) { @@ -445,12 +461,12 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type, } if (impl->TargetType == cmStateEnums::SHARED_LIBRARY || impl->TargetType == cmStateEnums::EXECUTABLE) { - InitProperty("WINDOWS_EXPORT_ALL_SYMBOLS", nullptr); + initProp("WINDOWS_EXPORT_ALL_SYMBOLS"); } if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY && this->GetType() != cmStateEnums::UTILITY) { - InitProperty("POSITION_INDEPENDENT_CODE", nullptr); + initProp("POSITION_INDEPENDENT_CODE"); } // Record current policies for later use. @@ -466,12 +482,12 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type, if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY && this->GetType() != cmStateEnums::UTILITY) { - InitProperty("JOB_POOL_COMPILE", nullptr); - InitProperty("JOB_POOL_LINK", nullptr); + initProp("JOB_POOL_COMPILE"); + initProp("JOB_POOL_LINK"); } if (impl->TargetType <= cmStateEnums::UTILITY) { - InitProperty("DOTNET_TARGET_FRAMEWORK_VERSION", nullptr); + initProp("DOTNET_TARGET_FRAMEWORK_VERSION"); } if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY && @@ -483,8 +499,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; - cmSystemTools::ExpandListArgument(globals, props); + std::vector<std::string> props = cmExpandedList(globals); const std::string vsGlobal = "VS_GLOBAL_"; for (const std::string& i : props) { // split NAME=VALUE @@ -492,7 +507,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type, if (assignment != std::string::npos) { const std::string propName = vsGlobal + i.substr(0, assignment); const std::string propValue = i.substr(assignment + 1); - InitProperty(propName, propValue.c_str()); + initPropValue(propName, propValue.c_str()); } } } @@ -726,8 +741,7 @@ public: bool operator()(std::string const& entry) { - std::vector<std::string> files; - cmSystemTools::ExpandListArgument(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), @@ -761,8 +775,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); } @@ -930,8 +943,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) { @@ -1070,21 +1082,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,7 +1184,7 @@ void cmTarget::SetProperty(const std::string& prop, const char* value) impl->SourceBacktraces.push_back(lfbt); } } else if (prop == propIMPORTED_GLOBAL) { - if (!cmSystemTools::IsOn(value)) { + if (!cmIsOn(value)) { std::ostringstream e; e << "IMPORTED_GLOBAL property can't be set to FALSE on targets (\"" << impl->Name << "\")\n"; @@ -1211,9 +1221,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()) { @@ -1496,7 +1505,6 @@ const char* cmTarget::GetComputedProperty( const char* cmTarget::GetProperty(const std::string& prop) const { - static std::unordered_set<std::string> specialProps; #define MAKE_STATIC_PROP(PROP) static const std::string prop##PROP = #PROP MAKE_STATIC_PROP(LINK_LIBRARIES); MAKE_STATIC_PROP(TYPE); @@ -1514,23 +1522,23 @@ const char* cmTarget::GetProperty(const std::string& prop) const MAKE_STATIC_PROP(SOURCE_DIR); MAKE_STATIC_PROP(SOURCES); #undef MAKE_STATIC_PROP - if (specialProps.empty()) { - specialProps.insert(propLINK_LIBRARIES); - specialProps.insert(propTYPE); - specialProps.insert(propINCLUDE_DIRECTORIES); - specialProps.insert(propCOMPILE_FEATURES); - specialProps.insert(propCOMPILE_OPTIONS); - specialProps.insert(propCOMPILE_DEFINITIONS); - specialProps.insert(propLINK_OPTIONS); - specialProps.insert(propLINK_DIRECTORIES); - specialProps.insert(propIMPORTED); - specialProps.insert(propIMPORTED_GLOBAL); - specialProps.insert(propMANUALLY_ADDED_DEPENDENCIES); - specialProps.insert(propNAME); - specialProps.insert(propBINARY_DIR); - specialProps.insert(propSOURCE_DIR); - specialProps.insert(propSOURCES); - } + static std::unordered_set<std::string> const specialProps{ + propLINK_LIBRARIES, + propTYPE, + propINCLUDE_DIRECTORIES, + propCOMPILE_FEATURES, + propCOMPILE_OPTIONS, + propCOMPILE_DEFINITIONS, + propLINK_OPTIONS, + propLINK_DIRECTORIES, + propIMPORTED, + propIMPORTED_GLOBAL, + propMANUALLY_ADDED_DEPENDENCIES, + propNAME, + propBINARY_DIR, + propSOURCE_DIR, + propSOURCES + }; if (specialProps.count(prop)) { if (prop == propLINK_LIBRARIES) { if (impl->LinkImplementationPropertyEntries.empty()) { @@ -1655,7 +1663,7 @@ const char* cmTarget::GetSafeProperty(const std::string& prop) const bool cmTarget::GetPropertyAsBool(const std::string& prop) const { - return cmSystemTools::IsOn(this->GetProperty(prop)); + return cmIsOn(this->GetProperty(prop)); } cmPropertyMap const& cmTarget::GetProperties() const @@ -1663,6 +1671,16 @@ cmPropertyMap const& cmTarget::GetProperties() const return impl->Properties; } +bool cmTarget::IsDLLPlatform() const +{ + return impl->IsDLLPlatform; +} + +bool cmTarget::IsAIX() const +{ + return impl->IsAIX; +} + bool cmTarget::IsImported() const { return impl->IsImportedTarget; @@ -1704,7 +1722,8 @@ const char* cmTarget::GetSuffixVariableInternal( ? "CMAKE_SHARED_LIBRARY_SUFFIX" : "CMAKE_EXECUTABLE_SUFFIX"); case cmStateEnums::ImportLibraryArtifact: - return "CMAKE_IMPORT_LIBRARY_SUFFIX"; + return (impl->IsAIX ? "CMAKE_AIX_IMPORT_FILE_SUFFIX" + : "CMAKE_IMPORT_LIBRARY_SUFFIX"); } break; default: @@ -1744,7 +1763,8 @@ const char* cmTarget::GetPrefixVariableInternal( ? "CMAKE_SHARED_LIBRARY_PREFIX" : ""); case cmStateEnums::ImportLibraryArtifact: - return "CMAKE_IMPORT_LIBRARY_PREFIX"; + return (impl->IsAIX ? "CMAKE_AIX_IMPORT_FILE_PREFIX" + : "CMAKE_IMPORT_LIBRARY_PREFIX"); } break; default: @@ -1778,8 +1798,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 = @@ -1794,8 +1813,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 = @@ -1808,8 +1826,7 @@ std::string cmTarget::ImportedGetFullPath( } if (result.empty()) { - result = this->GetName(); - result += "-NOTFOUND"; + result = cmStrCat(this->GetName(), "-NOTFOUND"); } return result; } @@ -1863,24 +1880,23 @@ 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)) { - cmSystemTools::ExpandListArgument(mapValue, mappedConfigs, true); + cmExpandList(mapValue, mappedConfigs, true); } } // If we needed to find one of the mapped configurations but did not // On a DLL platform there may be only IMPORTED_IMPLIB for a shared // library or an executable with exports. - bool allowImp = (impl->DLLPlatform && + bool allowImp = (this->IsDLLPlatform() && (this->GetType() == cmStateEnums::SHARED_LIBRARY || - this->IsExecutableWithExports())); + this->IsExecutableWithExports())) || + (this->IsAIX() && this->IsExecutableWithExports()); // If a mapping was found, check its configurations. for (std::vector<std::string>::const_iterator mci = mappedConfigs.begin(); @@ -1899,19 +1915,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); } } } @@ -1928,12 +1941,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); } } @@ -1957,19 +1968,16 @@ bool cmTarget::GetMappedConfig(std::string const& desired_config, if (!*loc && !*imp) { std::vector<std::string> availableConfigs; if (const char* iconfigs = this->GetProperty("IMPORTED_CONFIGURATIONS")) { - cmSystemTools::ExpandListArgument(iconfigs, availableConfigs); + cmExpandList(iconfigs, availableConfigs); } 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 2bd9e6d..2b75879 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -6,7 +6,7 @@ #include "cmConfigure.h" // IWYU pragma: keep #include <iosfwd> -#include <memory> // IWYU pragma: keep +#include <memory> #include <set> #include <string> #include <utility> @@ -16,6 +16,7 @@ #include "cmListFileCache.h" #include "cmPolicies.h" #include "cmStateTypes.h" +#include "cmStringAlgorithms.h" #include "cmTargetLinkLibraryType.h" class cmCustomCommand; @@ -181,6 +182,12 @@ public: //! Get all properties cmPropertyMap const& GetProperties() const; + //! Return whether or not the target is for a DLL platform. + bool IsDLLPlatform() const; + + //! Return whether or not we are targeting AIX. + bool IsAIX() const; + bool IsImported() const; bool IsImportedGloballyVisible() const; diff --git a/Source/cmTargetCompileDefinitionsCommand.cxx b/Source/cmTargetCompileDefinitionsCommand.cxx index c4dc838..b64646a 100644 --- a/Source/cmTargetCompileDefinitionsCommand.cxx +++ b/Source/cmTargetCompileDefinitionsCommand.cxx @@ -4,9 +4,9 @@ #include <sstream> -#include "cmAlgorithms.h" #include "cmMakefile.h" #include "cmMessageType.h" +#include "cmStringAlgorithms.h" #include "cmTarget.h" class cmExecutionStatus; diff --git a/Source/cmTargetCompileDefinitionsCommand.h b/Source/cmTargetCompileDefinitionsCommand.h index d41483a..25af21d 100644 --- a/Source/cmTargetCompileDefinitionsCommand.h +++ b/Source/cmTargetCompileDefinitionsCommand.h @@ -8,9 +8,11 @@ #include <string> #include <vector> +#include "cm_memory.hxx" + +#include "cmCommand.h" #include "cmTargetPropCommandBase.h" -class cmCommand; class cmExecutionStatus; class cmTarget; @@ -20,7 +22,10 @@ public: /** * This is a virtual constructor for the command. */ - cmCommand* Clone() override { return new cmTargetCompileDefinitionsCommand; } + std::unique_ptr<cmCommand> Clone() override + { + return cm::make_unique<cmTargetCompileDefinitionsCommand>(); + } /** * This is called when the command is first encountered in diff --git a/Source/cmTargetCompileFeaturesCommand.cxx b/Source/cmTargetCompileFeaturesCommand.cxx index c9e394b..976c8cb 100644 --- a/Source/cmTargetCompileFeaturesCommand.cxx +++ b/Source/cmTargetCompileFeaturesCommand.cxx @@ -4,9 +4,9 @@ #include <sstream> -#include "cmAlgorithms.h" #include "cmMakefile.h" #include "cmMessageType.h" +#include "cmStringAlgorithms.h" class cmExecutionStatus; class cmTarget; diff --git a/Source/cmTargetCompileFeaturesCommand.h b/Source/cmTargetCompileFeaturesCommand.h index 45240a5..07948fa 100644 --- a/Source/cmTargetCompileFeaturesCommand.h +++ b/Source/cmTargetCompileFeaturesCommand.h @@ -8,15 +8,20 @@ #include <string> #include <vector> +#include "cm_memory.hxx" + +#include "cmCommand.h" #include "cmTargetPropCommandBase.h" -class cmCommand; class cmExecutionStatus; class cmTarget; class cmTargetCompileFeaturesCommand : public cmTargetPropCommandBase { - cmCommand* Clone() override { return new cmTargetCompileFeaturesCommand; } + std::unique_ptr<cmCommand> Clone() override + { + return cm::make_unique<cmTargetCompileFeaturesCommand>(); + } bool InitialPass(std::vector<std::string> const& args, cmExecutionStatus& status) override; diff --git a/Source/cmTargetCompileOptionsCommand.cxx b/Source/cmTargetCompileOptionsCommand.cxx index 8b4763a..7dadb82 100644 --- a/Source/cmTargetCompileOptionsCommand.cxx +++ b/Source/cmTargetCompileOptionsCommand.cxx @@ -4,10 +4,10 @@ #include <sstream> -#include "cmAlgorithms.h" #include "cmListFileCache.h" #include "cmMakefile.h" #include "cmMessageType.h" +#include "cmStringAlgorithms.h" #include "cmTarget.h" class cmExecutionStatus; diff --git a/Source/cmTargetCompileOptionsCommand.h b/Source/cmTargetCompileOptionsCommand.h index 6fb151a..a571cfb 100644 --- a/Source/cmTargetCompileOptionsCommand.h +++ b/Source/cmTargetCompileOptionsCommand.h @@ -8,9 +8,11 @@ #include <string> #include <vector> +#include "cm_memory.hxx" + +#include "cmCommand.h" #include "cmTargetPropCommandBase.h" -class cmCommand; class cmExecutionStatus; class cmTarget; @@ -20,7 +22,10 @@ public: /** * This is a virtual constructor for the command. */ - cmCommand* Clone() override { return new cmTargetCompileOptionsCommand; } + std::unique_ptr<cmCommand> Clone() override + { + return cm::make_unique<cmTargetCompileOptionsCommand>(); + } /** * This is called when the command is first encountered in diff --git a/Source/cmTargetDepend.h b/Source/cmTargetDepend.h index 5ea0085..4ca78fa 100644 --- a/Source/cmTargetDepend.h +++ b/Source/cmTargetDepend.h @@ -31,7 +31,7 @@ public: operator cmGeneratorTarget const*() const { return this->Target; } cmGeneratorTarget const* operator->() const { return this->Target; } cmGeneratorTarget const& operator*() const { return *this->Target; } - friend bool operator<(cmTargetDepend l, cmTargetDepend r) + friend bool operator<(cmTargetDepend const& l, cmTargetDepend const& r) { return l.Target < r.Target; } diff --git a/Source/cmTargetIncludeDirectoriesCommand.cxx b/Source/cmTargetIncludeDirectoriesCommand.cxx index d6918c0..d099349 100644 --- a/Source/cmTargetIncludeDirectoriesCommand.cxx +++ b/Source/cmTargetIncludeDirectoriesCommand.cxx @@ -9,6 +9,7 @@ #include "cmListFileCache.h" #include "cmMakefile.h" #include "cmMessageType.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmTarget.h" @@ -39,9 +40,9 @@ std::string cmTargetIncludeDirectoriesCommand::Join( for (std::string const& it : content) { if (cmSystemTools::FileIsFullPath(it) || cmGeneratorExpression::Find(it) == 0) { - dirs += sep + it; + dirs += cmStrCat(sep, it); } else { - dirs += sep + prefix + it; + dirs += cmStrCat(sep, prefix, it); } sep = ";"; } diff --git a/Source/cmTargetIncludeDirectoriesCommand.h b/Source/cmTargetIncludeDirectoriesCommand.h index 57bf8fc..6defab2 100644 --- a/Source/cmTargetIncludeDirectoriesCommand.h +++ b/Source/cmTargetIncludeDirectoriesCommand.h @@ -8,9 +8,11 @@ #include <string> #include <vector> +#include "cm_memory.hxx" + +#include "cmCommand.h" #include "cmTargetPropCommandBase.h" -class cmCommand; class cmExecutionStatus; class cmTarget; @@ -20,7 +22,10 @@ public: /** * This is a virtual constructor for the command. */ - cmCommand* Clone() override { return new cmTargetIncludeDirectoriesCommand; } + std::unique_ptr<cmCommand> Clone() override + { + return cm::make_unique<cmTargetIncludeDirectoriesCommand>(); + } /** * This is called when the command is first encountered in diff --git a/Source/cmTargetLinkDirectoriesCommand.cxx b/Source/cmTargetLinkDirectoriesCommand.cxx index 269f751..435c392 100644 --- a/Source/cmTargetLinkDirectoriesCommand.cxx +++ b/Source/cmTargetLinkDirectoriesCommand.cxx @@ -4,11 +4,11 @@ #include <sstream> -#include "cmAlgorithms.h" #include "cmGeneratorExpression.h" #include "cmListFileCache.h" #include "cmMakefile.h" #include "cmMessageType.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmTarget.h" diff --git a/Source/cmTargetLinkDirectoriesCommand.h b/Source/cmTargetLinkDirectoriesCommand.h index 52c75a0..a2fcfa9 100644 --- a/Source/cmTargetLinkDirectoriesCommand.h +++ b/Source/cmTargetLinkDirectoriesCommand.h @@ -8,9 +8,11 @@ #include <string> #include <vector> +#include "cm_memory.hxx" + +#include "cmCommand.h" #include "cmTargetPropCommandBase.h" -class cmCommand; class cmExecutionStatus; class cmTarget; @@ -20,7 +22,10 @@ public: /** * This is a virtual constructor for the command. */ - cmCommand* Clone() override { return new cmTargetLinkDirectoriesCommand; } + std::unique_ptr<cmCommand> Clone() override + { + return cm::make_unique<cmTargetLinkDirectoriesCommand>(); + } /** * This is called when the command is first encountered in 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/cmTargetLinkLibrariesCommand.h b/Source/cmTargetLinkLibrariesCommand.h index 54f8cf4..6698ce0 100644 --- a/Source/cmTargetLinkLibrariesCommand.h +++ b/Source/cmTargetLinkLibrariesCommand.h @@ -8,6 +8,8 @@ #include <string> #include <vector> +#include "cm_memory.hxx" + #include "cmCommand.h" #include "cmTargetLinkLibraryType.h" @@ -30,7 +32,10 @@ public: /** * This is a virtual constructor for the command. */ - cmCommand* Clone() override { return new cmTargetLinkLibrariesCommand; } + std::unique_ptr<cmCommand> Clone() override + { + return cm::make_unique<cmTargetLinkLibrariesCommand>(); + } /** * This is called when the command is first encountered in diff --git a/Source/cmTargetLinkOptionsCommand.cxx b/Source/cmTargetLinkOptionsCommand.cxx index 5366486..2866cf1 100644 --- a/Source/cmTargetLinkOptionsCommand.cxx +++ b/Source/cmTargetLinkOptionsCommand.cxx @@ -4,10 +4,10 @@ #include <sstream> -#include "cmAlgorithms.h" #include "cmListFileCache.h" #include "cmMakefile.h" #include "cmMessageType.h" +#include "cmStringAlgorithms.h" #include "cmTarget.h" class cmExecutionStatus; diff --git a/Source/cmTargetLinkOptionsCommand.h b/Source/cmTargetLinkOptionsCommand.h index a1fc9fc..3710739 100644 --- a/Source/cmTargetLinkOptionsCommand.h +++ b/Source/cmTargetLinkOptionsCommand.h @@ -8,9 +8,11 @@ #include <string> #include <vector> +#include "cm_memory.hxx" + +#include "cmCommand.h" #include "cmTargetPropCommandBase.h" -class cmCommand; class cmExecutionStatus; class cmTarget; @@ -20,7 +22,10 @@ public: /** * This is a virtual constructor for the command. */ - cmCommand* Clone() override { return new cmTargetLinkOptionsCommand; } + std::unique_ptr<cmCommand> Clone() override + { + return cm::make_unique<cmTargetLinkOptionsCommand>(); + } /** * This is called when the command is first encountered in diff --git a/Source/cmTargetPropCommandBase.cxx b/Source/cmTargetPropCommandBase.cxx index 1b8ee81..3aa845c 100644 --- a/Source/cmTargetPropCommandBase.cxx +++ b/Source/cmTargetPropCommandBase.cxx @@ -32,12 +32,13 @@ bool cmTargetPropCommandBase::HandleArguments( this->HandleMissingTarget(args[0]); return false; } - if ((this->Target->GetType() != cmStateEnums::SHARED_LIBRARY) && + if ((this->Target->GetType() != cmStateEnums::EXECUTABLE) && (this->Target->GetType() != cmStateEnums::STATIC_LIBRARY) && - (this->Target->GetType() != cmStateEnums::OBJECT_LIBRARY) && + (this->Target->GetType() != cmStateEnums::SHARED_LIBRARY) && (this->Target->GetType() != cmStateEnums::MODULE_LIBRARY) && + (this->Target->GetType() != cmStateEnums::OBJECT_LIBRARY) && (this->Target->GetType() != cmStateEnums::INTERFACE_LIBRARY) && - (this->Target->GetType() != cmStateEnums::EXECUTABLE)) { + (this->Target->GetType() != cmStateEnums::UNKNOWN_LIBRARY)) { this->SetError("called with non-compilable target type"); return false; } diff --git a/Source/cmTargetPropertyComputer.cxx b/Source/cmTargetPropertyComputer.cxx index 3f763af..baab8da 100644 --- a/Source/cmTargetPropertyComputer.cxx +++ b/Source/cmTargetPropertyComputer.cxx @@ -11,6 +11,7 @@ #include "cmMessenger.h" #include "cmPolicies.h" #include "cmStateSnapshot.h" +#include "cmStringAlgorithms.h" bool cmTargetPropertyComputer::HandleLocationPropertyPolicy( std::string const& tgtName, cmMessenger* messenger, @@ -56,22 +57,21 @@ bool cmTargetPropertyComputer::WhiteListedInterfaceProperty( if (std::islower(prop[0])) { return true; } - static std::unordered_set<std::string> builtIns; - if (builtIns.empty()) { - builtIns.insert("COMPATIBLE_INTERFACE_BOOL"); - builtIns.insert("COMPATIBLE_INTERFACE_NUMBER_MAX"); - builtIns.insert("COMPATIBLE_INTERFACE_NUMBER_MIN"); - builtIns.insert("COMPATIBLE_INTERFACE_STRING"); - builtIns.insert("EXPORT_NAME"); - builtIns.insert("EXPORT_PROPERTIES"); - builtIns.insert("IMPORTED"); - builtIns.insert("IMPORTED_GLOBAL"); - builtIns.insert("MANUALLY_ADDED_DEPENDENCIES"); - builtIns.insert("NAME"); - builtIns.insert("PRIVATE_HEADER"); - builtIns.insert("PUBLIC_HEADER"); - builtIns.insert("TYPE"); - } + static std::unordered_set<std::string> const builtIns{ + "COMPATIBLE_INTERFACE_BOOL", + "COMPATIBLE_INTERFACE_NUMBER_MAX", + "COMPATIBLE_INTERFACE_NUMBER_MIN", + "COMPATIBLE_INTERFACE_STRING", + "EXPORT_NAME", + "EXPORT_PROPERTIES", + "IMPORTED", + "IMPORTED_GLOBAL", + "MANUALLY_ADDED_DEPENDENCIES", + "NAME", + "PRIVATE_HEADER", + "PUBLIC_HEADER", + "TYPE" + }; if (builtIns.count(prop)) { return true; diff --git a/Source/cmTargetPropertyComputer.h b/Source/cmTargetPropertyComputer.h index efbf95f..3b11acd 100644 --- a/Source/cmTargetPropertyComputer.h +++ b/Source/cmTargetPropertyComputer.h @@ -7,9 +7,9 @@ #include <string> -#include "cmAlgorithms.h" #include "cmListFileCache.h" #include "cmStateTypes.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" class cmMessenger; diff --git a/Source/cmTargetSourcesCommand.cxx b/Source/cmTargetSourcesCommand.cxx index 11e288f..2251a65 100644 --- a/Source/cmTargetSourcesCommand.cxx +++ b/Source/cmTargetSourcesCommand.cxx @@ -4,11 +4,11 @@ #include <sstream> -#include "cmAlgorithms.h" #include "cmGeneratorExpression.h" #include "cmMakefile.h" #include "cmMessageType.h" #include "cmPolicies.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmTarget.h" @@ -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/cmTargetSourcesCommand.h b/Source/cmTargetSourcesCommand.h index b01e3ca..90fd45f 100644 --- a/Source/cmTargetSourcesCommand.h +++ b/Source/cmTargetSourcesCommand.h @@ -8,9 +8,11 @@ #include <string> #include <vector> +#include "cm_memory.hxx" + +#include "cmCommand.h" #include "cmTargetPropCommandBase.h" -class cmCommand; class cmExecutionStatus; class cmTarget; @@ -20,7 +22,10 @@ public: /** * This is a virtual constructor for the command. */ - cmCommand* Clone() override { return new cmTargetSourcesCommand; } + std::unique_ptr<cmCommand> Clone() override + { + return cm::make_unique<cmTargetSourcesCommand>(); + } /** * This is called when the command is first encountered in diff --git a/Source/cmTest.cxx b/Source/cmTest.cxx index 7d45cf5..d5c61c1 100644 --- a/Source/cmTest.cxx +++ b/Source/cmTest.cxx @@ -5,10 +5,11 @@ #include "cmMakefile.h" #include "cmProperty.h" #include "cmState.h" -#include "cmSystemTools.h" +#include "cmStringAlgorithms.h" cmTest::cmTest(cmMakefile* mf) - : Backtrace(mf->GetBacktrace()) + : CommandExpandLists(false) + , Backtrace(mf->GetBacktrace()) { this->Makefile = mf; this->OldStyle = true; @@ -46,7 +47,7 @@ const char* cmTest::GetProperty(const std::string& prop) const bool cmTest::GetPropertyAsBool(const std::string& prop) const { - return cmSystemTools::IsOn(this->GetProperty(prop)); + return cmIsOn(this->GetProperty(prop)); } void cmTest::SetProperty(const std::string& prop, const char* value) @@ -59,3 +60,13 @@ void cmTest::AppendProperty(const std::string& prop, const char* value, { this->Properties.AppendProperty(prop, value, asString); } + +bool cmTest::GetCommandExpandLists() const +{ + return this->CommandExpandLists; +} + +void cmTest::SetCommandExpandLists(bool b) +{ + this->CommandExpandLists = b; +} diff --git a/Source/cmTest.h b/Source/cmTest.h index 88dc730..02d8f46 100644 --- a/Source/cmTest.h +++ b/Source/cmTest.h @@ -51,10 +51,15 @@ public: bool GetOldStyle() const { return this->OldStyle; } void SetOldStyle(bool b) { this->OldStyle = b; } + /** Set/Get whether lists in command lines should be expanded. */ + bool GetCommandExpandLists() const; + void SetCommandExpandLists(bool b); + private: cmPropertyMap Properties; std::string Name; std::vector<std::string> Command; + bool CommandExpandLists; bool OldStyle; diff --git a/Source/cmTestGenerator.cxx b/Source/cmTestGenerator.cxx index 571cd09..333d4d5 100644 --- a/Source/cmTestGenerator.cxx +++ b/Source/cmTestGenerator.cxx @@ -2,18 +2,20 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmTestGenerator.h" +#include <memory> #include <ostream> #include <utility> +#include <vector> #include "cmGeneratorExpression.h" #include "cmGeneratorTarget.h" #include "cmListFileCache.h" #include "cmLocalGenerator.h" #include "cmOutputConverter.h" -#include "cmProperty.h" #include "cmPropertyMap.h" #include "cmRange.h" #include "cmStateTypes.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmTest.h" @@ -76,12 +78,22 @@ void cmTestGenerator::GenerateScriptForConfig(std::ostream& os, // Start the test command. os << indent << "add_test(" << this->Test->GetName() << " "; - // Get the test command line to be executed. - std::vector<std::string> const& command = this->Test->GetCommand(); + // Evaluate command line arguments + std::vector<std::string> argv = + EvaluateCommandLineArguments(this->Test->GetCommand(), ge, config); + + // Expand arguments if COMMAND_EXPAND_LISTS is set + if (this->Test->GetCommandExpandLists()) { + argv = cmExpandedLists(argv.begin(), argv.end()); + // Expanding lists on an empty command may have left it empty + if (argv.empty()) { + argv.emplace_back(); + } + } // Check whether the command executable is a target whose name is to // be translated. - std::string exe = command[0]; + std::string exe = argv[0]; cmGeneratorTarget* target = this->LG->FindGeneratorTargetToUse(exe); if (target && target->GetType() == cmStateEnums::EXECUTABLE) { // Use the target file on disk. @@ -90,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; - cmSystemTools::ExpandListArgument(emulator, emulatorWithArgs); + std::vector<std::string> emulatorWithArgs = cmExpandedList(emulator); std::string emulatorExe(emulatorWithArgs[0]); cmSystemTools::ConvertToUnixSlashes(emulatorExe); os << cmOutputConverter::EscapeForCMake(emulatorExe) << " "; @@ -101,29 +112,26 @@ void cmTestGenerator::GenerateScriptForConfig(std::ostream& os, } } else { // Use the command name given. - exe = ge.Parse(exe)->Evaluate(this->LG, config); cmSystemTools::ConvertToUnixSlashes(exe); } // Generate the command line with full escapes. os << cmOutputConverter::EscapeForCMake(exe); - for (std::string const& arg : cmMakeRange(command).advance(1)) { - os << " " - << cmOutputConverter::EscapeForCMake( - ge.Parse(arg)->Evaluate(this->LG, config)); + + for (auto const& arg : cmMakeRange(argv).advance(1)) { + os << " " << cmOutputConverter::EscapeForCMake(arg); } // Finish the test command. os << ")\n"; // Output properties for the test. - cmPropertyMap& pm = this->Test->GetProperties(); os << indent << "set_tests_properties(" << this->Test->GetName() << " PROPERTIES "; - for (auto const& i : pm) { + for (auto const& i : this->Test->GetProperties().GetList()) { os << " " << i.first << " " << cmOutputConverter::EscapeForCMake( - ge.Parse(i.second.GetValue())->Evaluate(this->LG, config)); + ge.Parse(i.second)->Evaluate(this->LG, config)); } this->GenerateInternalProperties(os); os << ")" << std::endl; @@ -173,12 +181,11 @@ void cmTestGenerator::GenerateOldStyle(std::ostream& fout, Indent indent) fout << ")" << std::endl; // Output properties for the test. - cmPropertyMap& pm = this->Test->GetProperties(); fout << indent << "set_tests_properties(" << this->Test->GetName() << " PROPERTIES "; - for (auto const& i : pm) { + for (auto const& i : this->Test->GetProperties().GetList()) { fout << " " << i.first << " " - << cmOutputConverter::EscapeForCMake(i.second.GetValue()); + << cmOutputConverter::EscapeForCMake(i.second); } this->GenerateInternalProperties(fout); fout << ")" << std::endl; @@ -208,3 +215,16 @@ void cmTestGenerator::GenerateInternalProperties(std::ostream& os) os << "\""; } + +std::vector<std::string> cmTestGenerator::EvaluateCommandLineArguments( + const std::vector<std::string>& argv, cmGeneratorExpression& ge, + const std::string& config) const +{ + // Evaluate executable name and arguments + auto evaluatedRange = + cmMakeRange(argv).transform([&](const std::string& arg) { + return ge.Parse(arg)->Evaluate(this->LG, config); + }); + + return { evaluatedRange.begin(), evaluatedRange.end() }; +} diff --git a/Source/cmTestGenerator.h b/Source/cmTestGenerator.h index 8b9cf78..7ac68eb 100644 --- a/Source/cmTestGenerator.h +++ b/Source/cmTestGenerator.h @@ -11,6 +11,7 @@ #include <string> #include <vector> +class cmGeneratorExpression; class cmLocalGenerator; class cmTest; @@ -38,6 +39,9 @@ public: private: void GenerateInternalProperties(std::ostream& os); + std::vector<std::string> EvaluateCommandLineArguments( + const std::vector<std::string>& argv, cmGeneratorExpression& ge, + const std::string& config) const; protected: void GenerateScriptConfigs(std::ostream& os, Indent indent) override; diff --git a/Source/cmTimestamp.cxx b/Source/cmTimestamp.cxx index da5d21e..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, @@ -109,7 +110,7 @@ time_t cmTimestamp::CreateUtcTimeTFromTm(struct tm& tm) const time_t result = mktime(&tm); -# ifdef CMAKE_BUILD_WITH_CMAKE +# ifndef CMAKE_BOOTSTRAP if (tz_was_set) { cmSystemTools::PutEnv(tz_old); } else { @@ -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/cmTryCompileCommand.h b/Source/cmTryCompileCommand.h index 8237878..ec9f8b8 100644 --- a/Source/cmTryCompileCommand.h +++ b/Source/cmTryCompileCommand.h @@ -8,9 +8,11 @@ #include <string> #include <vector> +#include "cm_memory.hxx" + +#include "cmCommand.h" #include "cmCoreTryCompile.h" -class cmCommand; class cmExecutionStatus; /** \class cmTryCompileCommand @@ -24,7 +26,10 @@ public: /** * This is a virtual constructor for the command. */ - cmCommand* Clone() override { return new cmTryCompileCommand; } + std::unique_ptr<cmCommand> Clone() override + { + return cm::make_unique<cmTryCompileCommand>(); + } /** * This is called when the command is first encountered in diff --git a/Source/cmTryRunCommand.cxx b/Source/cmTryRunCommand.cxx index a92c2a0..24d0f0f 100644 --- a/Source/cmTryRunCommand.cxx +++ b/Source/cmTryRunCommand.cxx @@ -11,6 +11,7 @@ #include "cmRange.h" #include "cmState.h" #include "cmStateTypes.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmake.h" @@ -137,7 +138,7 @@ bool cmTryRunCommand::InitialPass(std::vector<std::string> const& argv, // now put the output into the variables if (!this->RunOutputVariable.empty()) { this->Makefile->AddDefinition(this->RunOutputVariable, - runOutputContents.c_str()); + runOutputContents); } if (!this->OutputVariable.empty()) { @@ -148,8 +149,7 @@ bool cmTryRunCommand::InitialPass(std::vector<std::string> const& argv, if (compileOutput) { runOutputContents = compileOutput + runOutputContents; } - this->Makefile->AddDefinition(this->OutputVariable, - runOutputContents.c_str()); + this->Makefile->AddDefinition(this->OutputVariable, runOutputContents); } } } @@ -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; - cmSystemTools::ExpandListArgument(emulator, emulatorWithArgs); + std::vector<std::string> emulatorWithArgs = cmExpandedList(emulator); finalCommand += cmSystemTools::ConvertToRunCommandPath(emulatorWithArgs[0]); finalCommand += " "; @@ -214,20 +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 += "/"; - 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"; @@ -236,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); @@ -259,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(), @@ -295,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 += @@ -344,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/cmTryRunCommand.h b/Source/cmTryRunCommand.h index c54622c..bacfcdb 100644 --- a/Source/cmTryRunCommand.h +++ b/Source/cmTryRunCommand.h @@ -8,9 +8,11 @@ #include <string> #include <vector> +#include "cm_memory.hxx" + +#include "cmCommand.h" #include "cmCoreTryCompile.h" -class cmCommand; class cmExecutionStatus; /** \class cmTryRunCommand @@ -24,7 +26,10 @@ public: /** * This is a virtual constructor for the command. */ - cmCommand* Clone() override { return new cmTryRunCommand; } + std::unique_ptr<cmCommand> Clone() override + { + return cm::make_unique<cmTryRunCommand>(); + } /** * This is called when the command is first encountered in diff --git a/Source/cmUVHandlePtr.cxx b/Source/cmUVHandlePtr.cxx index db67463..97c27cb 100644 --- a/Source/cmUVHandlePtr.cxx +++ b/Source/cmUVHandlePtr.cxx @@ -122,7 +122,7 @@ uv_handle_ptr_<T>::operator T*() const return this->handle.get(); } -#ifdef CMAKE_BUILD_WITH_CMAKE +#ifndef CMAKE_BOOTSTRAP template <> struct uv_handle_deleter<uv_async_t> { @@ -230,7 +230,7 @@ int uv_timer_ptr::start(uv_timer_cb cb, uint64_t timeout, uint64_t repeat) return uv_timer_start(*this, cb, timeout, repeat); } -#ifdef CMAKE_BUILD_WITH_CMAKE +#ifndef CMAKE_BOOTSTRAP uv_tty_ptr::operator uv_stream_t*() const { return reinterpret_cast<uv_stream_t*>(handle.get()); @@ -259,7 +259,7 @@ UV_HANDLE_PTR_INSTANTIATE_EXPLICIT(process) UV_HANDLE_PTR_INSTANTIATE_EXPLICIT(timer) -#ifdef CMAKE_BUILD_WITH_CMAKE +#ifndef CMAKE_BOOTSTRAP UV_HANDLE_PTR_INSTANTIATE_EXPLICIT(async) UV_HANDLE_PTR_INSTANTIATE_EXPLICIT(tty) diff --git a/Source/cmUVProcessChain.cxx b/Source/cmUVProcessChain.cxx index 90ece0b..56d6c09 100644 --- a/Source/cmUVProcessChain.cxx +++ b/Source/cmUVProcessChain.cxx @@ -2,7 +2,6 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmUVProcessChain.h" -#include "cmAlgorithms.h" #include "cmGetPipes.h" #include "cmUVHandlePtr.h" #include "cmUVStreambuf.h" @@ -10,10 +9,12 @@ #include <assert.h> +#include <istream> // IWYU pragma: keep #include <iterator> -#include <memory> #include <utility> +#include "cm_memory.hxx" + struct cmUVProcessChain::InternalData { struct BasicStreamData diff --git a/Source/cmUVProcessChain.h b/Source/cmUVProcessChain.h index 2b33520..75f8f66 100644 --- a/Source/cmUVProcessChain.h +++ b/Source/cmUVProcessChain.h @@ -7,7 +7,7 @@ #include <array> #include <iosfwd> -#include <memory> // IWYU pragma: keep +#include <memory> #include <string> #include <vector> diff --git a/Source/cmUnexpectedCommand.cxx b/Source/cmUnexpectedCommand.cxx deleted file mode 100644 index a8de9e6..0000000 --- a/Source/cmUnexpectedCommand.cxx +++ /dev/null @@ -1,22 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing for details. */ -#include "cmUnexpectedCommand.h" - -#include <stdlib.h> - -#include "cmMakefile.h" - -class cmExecutionStatus; - -bool cmUnexpectedCommand::InitialPass(std::vector<std::string> const&, - cmExecutionStatus&) -{ - const char* versionValue = - this->Makefile->GetDefinition("CMAKE_MINIMUM_REQUIRED_VERSION"); - if (this->Name == "endif" && (!versionValue || atof(versionValue) <= 1.4)) { - return true; - } - - this->SetError(this->Error); - return false; -} diff --git a/Source/cmUnexpectedCommand.h b/Source/cmUnexpectedCommand.h deleted file mode 100644 index 33d6bdc..0000000 --- a/Source/cmUnexpectedCommand.h +++ /dev/null @@ -1,38 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing for details. */ -#ifndef cmUnexpectedCommand_h -#define cmUnexpectedCommand_h - -#include "cmConfigure.h" // IWYU pragma: keep - -#include <string> -#include <utility> -#include <vector> - -#include "cmCommand.h" - -class cmExecutionStatus; - -class cmUnexpectedCommand : public cmCommand -{ -public: - cmUnexpectedCommand(std::string name, const char* error) - : Name(std::move(name)) - , Error(error) - { - } - - cmCommand* Clone() override - { - return new cmUnexpectedCommand(this->Name, this->Error); - } - - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; - -private: - std::string Name; - const char* Error; -}; - -#endif diff --git a/Source/cmUnsetCommand.cxx b/Source/cmUnsetCommand.cxx index cfaa1fd2..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 "cmAlgorithms.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; } @@ -24,27 +23,27 @@ bool cmUnsetCommand::InitialPass(std::vector<std::string> const& args, // what is the variable name auto const& envVarName = variable.substr(4, variable.size() - 5); -#ifdef CMAKE_BUILD_WITH_CMAKE +#ifndef CMAKE_BOOTSTRAP cmSystemTools::UnsetEnv(envVarName.c_str()); #endif return true; } // 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 4e1208a..be4c166 100644 --- a/Source/cmUnsetCommand.h +++ b/Source/cmUnsetCommand.h @@ -8,29 +8,14 @@ #include <string> #include <vector> -#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. - */ - cmCommand* Clone() override { return new 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..3d83760 100644 --- a/Source/cmUseMangledMesaCommand.cxx +++ b/Source/cmUseMangledMesaCommand.cxx @@ -5,6 +5,7 @@ #include "cmsys/FStream.hxx" #include "cmsys/RegularExpression.hxx" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" class cmExecutionStatus; @@ -20,13 +21,9 @@ bool cmUseMangledMesaCommand::InitialPass(std::vector<std::string> const& args, 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 += " "; + std::string e = cmStrCat("Bad path to Mesa, could not find: ", glh, ' '); this->SetError(e); return false; } @@ -39,9 +36,7 @@ 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; + std::string path = cmStrCat(inputDir, '/', f); this->CopyAndFullPathMesaHeader(path, destDir); } @@ -51,13 +46,11 @@ bool cmUseMangledMesaCommand::InitialPass(std::vector<std::string> const& args, void cmUseMangledMesaCommand::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: " + diff --git a/Source/cmUseMangledMesaCommand.h b/Source/cmUseMangledMesaCommand.h index e2f1d9b..1c01596 100644 --- a/Source/cmUseMangledMesaCommand.h +++ b/Source/cmUseMangledMesaCommand.h @@ -8,6 +8,8 @@ #include <string> #include <vector> +#include "cm_memory.hxx" + #include "cmCommand.h" class cmExecutionStatus; @@ -15,7 +17,10 @@ class cmExecutionStatus; class cmUseMangledMesaCommand : public cmCommand { public: - cmCommand* Clone() override { return new cmUseMangledMesaCommand; } + std::unique_ptr<cmCommand> Clone() override + { + return cm::make_unique<cmUseMangledMesaCommand>(); + } bool InitialPass(std::vector<std::string> const& args, cmExecutionStatus& status) override; diff --git a/Source/cmUtilitySourceCommand.cxx b/Source/cmUtilitySourceCommand.cxx index b59a587..d255b67 100644 --- a/Source/cmUtilitySourceCommand.cxx +++ b/Source/cmUtilitySourceCommand.cxx @@ -7,6 +7,7 @@ #include "cmMakefile.h" #include "cmState.h" #include "cmStateTypes.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" class cmExecutionStatus; @@ -35,11 +36,11 @@ bool cmUtilitySourceCommand::InitialPass(std::vector<std::string> const& args, if (this->Makefile->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 { diff --git a/Source/cmUtilitySourceCommand.h b/Source/cmUtilitySourceCommand.h index 165ecef..cef7fed 100644 --- a/Source/cmUtilitySourceCommand.h +++ b/Source/cmUtilitySourceCommand.h @@ -8,6 +8,8 @@ #include <string> #include <vector> +#include "cm_memory.hxx" + #include "cmCommand.h" class cmExecutionStatus; @@ -15,7 +17,10 @@ class cmExecutionStatus; class cmUtilitySourceCommand : public cmCommand { public: - cmCommand* Clone() override { return new cmUtilitySourceCommand; } + std::unique_ptr<cmCommand> Clone() override + { + return cm::make_unique<cmUtilitySourceCommand>(); + } bool InitialPass(std::vector<std::string> const& args, cmExecutionStatus& status) override; }; diff --git a/Source/cmUuid.cxx b/Source/cmUuid.cxx index 51ecbd1..0dc6ca7 100644 --- a/Source/cmUuid.cxx +++ b/Source/cmUuid.cxx @@ -114,14 +114,12 @@ std::string cmUuid::BinaryToString(const unsigned char* input) const std::string cmUuid::ByteToHex(unsigned char byte) const { - std::string result; + std::string result(" "); for (int i = 0; i < 2; ++i) { unsigned char rest = byte % 16; byte /= 16; - char c = (rest < 0xA) ? char('0' + rest) : char('a' + (rest - 0xA)); - - result = c + result; + result.at(1 - i) = c; } return result; diff --git a/Source/cmVSSetupHelper.cxx b/Source/cmVSSetupHelper.cxx index c78361e..707ceac 100644 --- a/Source/cmVSSetupHelper.cxx +++ b/Source/cmVSSetupHelper.cxx @@ -2,6 +2,7 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmVSSetupHelper.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmsys/Encoding.hxx" #include "cmsys/FStream.hxx" @@ -195,7 +196,7 @@ bool cmVSSetupAPIHelper::GetVSInstanceInfo( if (!fin || !cmSystemTools::GetLineFromStream(fin, vcToolsVersion)) { return false; } - vcToolsVersion = cmSystemTools::TrimWhitespace(vcToolsVersion); + vcToolsVersion = cmTrimWhitespace(vcToolsVersion); std::string const vcToolsDir = vcRoot + "/VC/Tools/MSVC/" + vcToolsVersion; if (!cmSystemTools::FileIsDirectory(vcToolsDir)) { return false; @@ -364,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 c02157a..c44eeca 100644 --- a/Source/cmVariableRequiresCommand.cxx +++ b/Source/cmVariableRequiresCommand.cxx @@ -4,6 +4,7 @@ #include "cmMakefile.h" #include "cmState.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" class cmExecutionStatus; @@ -42,16 +43,15 @@ bool cmVariableRequiresCommand::InitialPass( // if reqVar is set to true, but requirementsMet is false , then // set reqVar to false. if (!reqVar || (!requirementsMet && this->Makefile->IsOn(reqVar))) { - this->Makefile->AddDefinition(resultVariable, requirementsMet); + this->Makefile->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 94970c5..38e7490 100644 --- a/Source/cmVariableRequiresCommand.h +++ b/Source/cmVariableRequiresCommand.h @@ -8,6 +8,8 @@ #include <string> #include <vector> +#include "cm_memory.hxx" + #include "cmCommand.h" class cmExecutionStatus; @@ -15,7 +17,10 @@ class cmExecutionStatus; class cmVariableRequiresCommand : public cmCommand { public: - cmCommand* Clone() override { return new cmVariableRequiresCommand; } + std::unique_ptr<cmCommand> Clone() override + { + return cm::make_unique<cmVariableRequiresCommand>(); + } bool InitialPass(std::vector<std::string> const& args, cmExecutionStatus& status) override; }; diff --git a/Source/cmVariableWatch.h b/Source/cmVariableWatch.h index 1230101..acac2c1 100644 --- a/Source/cmVariableWatch.h +++ b/Source/cmVariableWatch.h @@ -6,7 +6,7 @@ #include "cmConfigure.h" // IWYU pragma: keep #include <map> -#include <memory> // IWYU pragma: keep +#include <memory> #include <string> #include <vector> diff --git a/Source/cmVariableWatchCommand.cxx b/Source/cmVariableWatchCommand.cxx index 5fe55bd..db23efd 100644 --- a/Source/cmVariableWatchCommand.cxx +++ b/Source/cmVariableWatchCommand.cxx @@ -2,7 +2,9 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmVariableWatchCommand.h" +#include <memory> #include <sstream> +#include <utility> #include "cmExecutionStatus.h" #include "cmListFileCache.h" @@ -54,7 +56,7 @@ static void cmVariableWatchCommandVariableAccessed(const std::string& variable, newLFF.Arguments.emplace_back(stack, cmListFileArgument::Quoted, 9999); newLFF.Name = data->Command; newLFF.Line = 9999; - cmExecutionStatus status; + cmExecutionStatus status(*makefile); if (!makefile->ExecuteCommand(newLFF, status)) { std::ostringstream error; error << "Error in cmake code at\nUnknown:0:\n" @@ -84,21 +86,45 @@ static void deleteVariableWatchCallbackData(void* client_data) delete data; } -cmVariableWatchCommand::cmVariableWatchCommand() = default; - -cmVariableWatchCommand::~cmVariableWatchCommand() +/** This command does not really have a final pass but it needs to + stay alive since it owns variable watch callback information. */ +class FinalAction { - for (std::string const& wv : this->WatchedVariables) { - this->Makefile->GetCMakeInstance()->GetVariableWatch()->RemoveWatch( - wv, cmVariableWatchCommandVariableAccessed); +public: + FinalAction(cmMakefile* makefile, std::string variable) + : Action(std::make_shared<Impl>(makefile, std::move(variable))) + { } -} -bool cmVariableWatchCommand::InitialPass(std::vector<std::string> const& args, - cmExecutionStatus&) + void operator()(cmMakefile&) const {} + +private: + struct Impl + { + Impl(cmMakefile* makefile, std::string variable) + : Makefile(makefile) + , Variable(std::move(variable)) + { + } + + ~Impl() + { + this->Makefile->GetCMakeInstance()->GetVariableWatch()->RemoveWatch( + this->Variable, cmVariableWatchCommandVariableAccessed); + } + + cmMakefile* Makefile; + std::string Variable; + }; + + std::shared_ptr<Impl const> Action; +}; + +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]; @@ -109,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; } @@ -118,13 +144,14 @@ bool cmVariableWatchCommand::InitialPass(std::vector<std::string> const& args, data->InCallback = false; data->Command = command; - this->WatchedVariables.insert(variable); - if (!this->Makefile->GetCMakeInstance()->GetVariableWatch()->AddWatch( + if (!status.GetMakefile().GetCMakeInstance()->GetVariableWatch()->AddWatch( variable, cmVariableWatchCommandVariableAccessed, data, deleteVariableWatchCallbackData)) { deleteVariableWatchCallbackData(data); return false; } + status.GetMakefile().AddFinalAction( + FinalAction(&status.GetMakefile(), variable)); return true; } diff --git a/Source/cmVariableWatchCommand.h b/Source/cmVariableWatchCommand.h index 6a8115d..3f9f244 100644 --- a/Source/cmVariableWatchCommand.h +++ b/Source/cmVariableWatchCommand.h @@ -5,45 +5,16 @@ #include "cmConfigure.h" // IWYU pragma: keep -#include <set> #include <string> #include <vector> -#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. - */ - cmCommand* Clone() override { return new cmVariableWatchCommand; } - - //! Default constructor - cmVariableWatchCommand(); - - //! Destructor. - ~cmVariableWatchCommand() override; - - /** - * 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; - - /** This command does not really have a final pass but it needs to - stay alive since it owns variable watch callback information. */ - bool HasFinalPass() const override { return true; } - -protected: - std::set<std::string> WatchedVariables; -}; +bool cmVariableWatchCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 7d25713..13f6295 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -19,9 +19,10 @@ #include "windows.h" #include <iterator> -#include <memory> // IWYU pragma: keep #include <set> +#include "cm_memory.hxx" + static void ConvertToWindowsSlash(std::string& s); static std::string cmVS10EscapeXML(std::string arg) @@ -363,10 +364,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); @@ -505,6 +505,11 @@ void cmVisualStudio10TargetGenerator::Generate() if (targetFrameworkVersion) { e1.Element("TargetFrameworkVersion", targetFrameworkVersion); } + if (this->ProjectType == vcxproj && + this->GlobalGenerator->TargetsWindowsCE()) { + e1.Element("EnableRedirectPlatform", "true"); + e1.Element("RedirectPlatformValue", this->Platform); + } if (this->ProjectType == csproj && this->GlobalGenerator->TargetsWindowsCE()) { const char* targetFrameworkId = this->GeneratorTarget->GetProperty( @@ -622,9 +627,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); @@ -744,7 +748,7 @@ void cmVisualStudio10TargetGenerator::WritePackageReferences(Elem& e0) std::vector<std::string> packageReferences; if (const char* vsPackageReferences = this->GeneratorTarget->GetProperty("VS_PACKAGE_REFERENCES")) { - cmSystemTools::ExpandListArgument(vsPackageReferences, packageReferences); + cmExpandList(vsPackageReferences, packageReferences); } if (!packageReferences.empty()) { Elem e1(e0, "ItemGroup"); @@ -771,14 +775,14 @@ void cmVisualStudio10TargetGenerator::WriteDotNetReferences(Elem& e0) std::vector<std::string> references; if (const char* vsDotNetReferences = this->GeneratorTarget->GetProperty("VS_DOTNET_REFERENCES")) { - cmSystemTools::ExpandListArgument(vsDotNetReferences, references); + cmExpandList(vsDotNetReferences, references); } cmPropertyMap const& props = this->GeneratorTarget->Target->GetProperties(); - for (auto const& i : props) { + for (auto const& i : props.GetList()) { if (i.first.find("VS_DOTNET_REFERENCE_") == 0) { std::string name = i.first.substr(20); if (!name.empty()) { - std::string path = i.second.GetValue(); + std::string path = i.second; if (!cmsys::SystemTools::FileIsFullPath(path)) { path = this->Makefile->GetCurrentSourceDirectory() + "/" + path; } @@ -832,7 +836,7 @@ void cmVisualStudio10TargetGenerator::WriteDotNetReference( const char* privateReference = "True"; if (const char* value = this->GeneratorTarget->GetProperty( "VS_DOTNET_REFERENCES_COPY_LOCAL")) { - if (cmSystemTools::IsOff(value)) { + if (cmIsOff(value)) { privateReference = "False"; } } @@ -847,8 +851,8 @@ void cmVisualStudio10TargetGenerator::WriteImports(Elem& e0) const char* imports = this->GeneratorTarget->Target->GetProperty("VS_PROJECT_IMPORT"); if (imports) { - std::vector<std::string> argsSplit; - cmSystemTools::ExpandListArgument(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; @@ -870,10 +874,10 @@ void cmVisualStudio10TargetGenerator::WriteDotNetReferenceCustomTags( typedef std::map<std::string, std::string> CustomTags; CustomTags tags; cmPropertyMap const& props = this->GeneratorTarget->Target->GetProperties(); - for (const auto& i : props) { + for (const auto& i : props.GetList()) { if (i.first.find(refPropFullPrefix) == 0) { std::string refTag = i.first.substr(refPropFullPrefix.length()); - std::string refVal = i.second.GetValue(); + std::string refVal = i.second; if (!refTag.empty() && !refVal.empty()) { tags[refTag] = refVal; } @@ -967,12 +971,12 @@ void cmVisualStudio10TargetGenerator::WriteEmbeddedResourceGroup(Elem& e0) } } const cmPropertyMap& props = oi->GetProperties(); - for (const auto& p : props) { + for (const std::string& p : props.GetKeys()) { static const std::string propNamePrefix = "VS_CSHARP_"; - if (p.first.find(propNamePrefix) == 0) { - std::string tagName = p.first.substr(propNamePrefix.length()); + if (p.find(propNamePrefix) == 0) { + std::string tagName = p.substr(propNamePrefix.length()); if (!tagName.empty()) { - std::string value = props.GetPropertyValue(p.first); + std::string value = props.GetPropertyValue(p); if (!value.empty()) { e2.Element(tagName.c_str(), value); } @@ -1068,7 +1072,7 @@ void cmVisualStudio10TargetGenerator::WriteWinRTReferences(Elem& e0) std::vector<std::string> references; if (const char* vsWinRTReferences = this->GeneratorTarget->GetProperty("VS_WINRT_REFERENCES")) { - cmSystemTools::ExpandListArgument(vsWinRTReferences, references); + cmExpandList(vsWinRTReferences, references); } if (this->GlobalGenerator->TargetsWindowsPhone() && @@ -1266,8 +1270,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)) { @@ -1372,9 +1376,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()); } } @@ -1543,11 +1546,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) }; @@ -1942,11 +1943,11 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(Elem& e1, const std::string& enableDebug = cge->Evaluate(this->LocalGenerator, this->Configurations[i]); if (!enableDebug.empty()) { - e2.WritePlatformConfigTag( - "EnableDebuggingInformation", - "'$(Configuration)|$(Platform)'=='" + this->Configurations[i] + - "|" + this->Platform + "'", - cmSystemTools::IsOn(enableDebug) ? "true" : "false"); + e2.WritePlatformConfigTag("EnableDebuggingInformation", + "'$(Configuration)|$(Platform)'=='" + + this->Configurations[i] + "|" + + this->Platform + "'", + cmIsOn(enableDebug) ? "true" : "false"); } } } @@ -1963,7 +1964,7 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(Elem& e1, "DisableOptimizations", "'$(Configuration)|$(Platform)'=='" + this->Configurations[i] + "|" + this->Platform + "'", - (cmSystemTools::IsOn(disableOptimizations) ? "true" : "false")); + (cmIsOn(disableOptimizations) ? "true" : "false")); } } } @@ -2228,8 +2229,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 += ";"; @@ -2419,17 +2419,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); @@ -2597,8 +2594,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; @@ -2710,9 +2706,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()) { @@ -2737,7 +2731,7 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions( } } if (const char* winRT = clOptions.GetFlag("CompileAsWinRT")) { - if (cmSystemTools::IsOn(winRT)) { + if (cmIsOn(winRT)) { this->TargetCompileAsWinRT = true; } } @@ -3007,9 +3001,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()) { @@ -3250,15 +3242,32 @@ void cmVisualStudio10TargetGenerator::WriteManifestOptions( std::vector<cmSourceFile const*> manifest_srcs; this->GeneratorTarget->GetManifests(manifest_srcs, config); - if (!manifest_srcs.empty()) { - std::ostringstream oss; - for (cmSourceFile const* mi : manifest_srcs) { - std::string m = this->ConvertPath(mi->GetFullPath(), false); - ConvertToWindowsSlash(m); - oss << m << ";"; - } + + const char* dpiAware = this->GeneratorTarget->GetProperty("VS_DPI_AWARE"); + + if (!manifest_srcs.empty() || dpiAware) { Elem e2(e1, "Manifest"); - e2.Element("AdditionalManifestFiles", oss.str()); + if (!manifest_srcs.empty()) { + std::ostringstream oss; + for (cmSourceFile const* mi : manifest_srcs) { + std::string m = this->ConvertPath(mi->GetFullPath(), false); + ConvertToWindowsSlash(m); + oss << m << ";"; + } + e2.Element("AdditionalManifestFiles", oss.str()); + } + if (dpiAware) { + if (!strcmp(dpiAware, "PerMonitor")) { + e2.Element("EnableDpiAwareness", "PerMonitorHighDPIAware"); + } else if (cmIsOn(dpiAware)) { + e2.Element("EnableDpiAwareness", "true"); + } else if (cmIsOff(dpiAware)) { + e2.Element("EnableDpiAwareness", "false"); + } else { + cmSystemTools::Error("Bad parameter for VS_DPI_AWARE: " + + std::string(dpiAware)); + } + } } } @@ -3407,9 +3416,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; @@ -3421,8 +3428,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 += " "; @@ -3447,8 +3453,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: @@ -3463,9 +3468,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); @@ -3529,13 +3533,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); @@ -3735,8 +3738,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; @@ -3918,10 +3920,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"); @@ -4004,7 +4004,7 @@ void cmVisualStudio10TargetGenerator::WriteSDKReferences(Elem& e0) std::unique_ptr<Elem> spe1; if (const char* vsSDKReferences = this->GeneratorTarget->GetProperty("VS_SDK_REFERENCES")) { - cmSystemTools::ExpandListArgument(vsSDKReferences, sdkReferences); + cmExpandList(vsSDKReferences, sdkReferences); spe1 = cm::make_unique<Elem>(e0, "ItemGroup"); for (std::string const& ri : sdkReferences) { Elem(*spe1, "SDKReference").Attribute("Include", ri); @@ -4679,12 +4679,12 @@ void cmVisualStudio10TargetGenerator::GetCSharpSourceProperties( { if (this->ProjectType == csproj) { const cmPropertyMap& props = sf->GetProperties(); - for (auto const& p : props) { + for (const std::string& p : props.GetKeys()) { static const std::string propNamePrefix = "VS_CSHARP_"; - if (p.first.find(propNamePrefix) == 0) { - std::string tagName = p.first.substr(propNamePrefix.length()); + if (p.find(propNamePrefix) == 0) { + std::string tagName = p.substr(propNamePrefix.length()); if (!tagName.empty()) { - const std::string val = props.GetPropertyValue(p.first); + const std::string val = props.GetPropertyValue(p); if (!val.empty()) { tags[tagName] = val; } else { @@ -4728,8 +4728,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 e1b0c70..3e423e9 100644 --- a/Source/cmVisualStudioGeneratorOptions.cxx +++ b/Source/cmVisualStudioGeneratorOptions.cxx @@ -193,7 +193,7 @@ void cmVisualStudioGeneratorOptions::FixCudaCodeGeneration() std::string arch_name = arch[0]; std::vector<std::string> codes; if (!code.empty()) { - codes = cmSystemTools::tokenize(code[0], ","); + codes = cmTokenize(code[0], ","); } if (codes.empty()) { codes.push_back(arch_name); @@ -220,7 +220,7 @@ void cmVisualStudioGeneratorOptions::FixCudaCodeGeneration() cmSystemTools::ReplaceString(entry, "]", ""); cmSystemTools::ReplaceString(entry, "\"", ""); - std::vector<std::string> codes = cmSystemTools::tokenize(entry, ","); + std::vector<std::string> codes = cmTokenize(entry, ","); if (codes.size() >= 2) { auto gencode_arch = cm::cbegin(codes); for (auto ci = gencode_arch + 1; ci != cm::cend(codes); ++ci) { @@ -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/cmVisualStudioSlnParser.cxx b/Source/cmVisualStudioSlnParser.cxx index 9353276..9eaee11 100644 --- a/Source/cmVisualStudioSlnParser.cxx +++ b/Source/cmVisualStudioSlnParser.cxx @@ -2,6 +2,7 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmVisualStudioSlnParser.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmVisualStudioSlnData.h" #include "cmsys/FStream.hxx" @@ -192,8 +193,8 @@ bool cmVisualStudioSlnParser::State::Process( assert(!line.IsComment()); switch (this->Stack.top()) { case FileStateStart: - if (!cmSystemTools::StringStartsWith( - line.GetTag().c_str(), "Microsoft Visual Studio Solution File")) { + if (!cmHasLiteralPrefix(line.GetTag(), + "Microsoft Visual Studio Solution File")) { result.SetError(ResultErrorInputStructure, this->GetCurrentLine()); return false; } @@ -462,7 +463,7 @@ bool cmVisualStudioSlnParser::ParseImpl(std::istream& input, cmSlnData& output, if (!this->ParseBOM(input, line, state)) return false; do { - line = cmSystemTools::TrimWhitespace(line); + line = cmTrimWhitespace(line); if (line.empty()) continue; ParsedLine parsedLine; @@ -578,9 +579,9 @@ bool cmVisualStudioSlnParser::ParseKeyValuePair(const std::string& line, return true; } const std::string& key = line.substr(0, idxEqualSign); - parsedLine.SetTag(cmSystemTools::TrimWhitespace(key)); + parsedLine.SetTag(cmTrimWhitespace(key)); const std::string& value = line.substr(idxEqualSign + 1); - parsedLine.AddValue(cmSystemTools::TrimWhitespace(value)); + parsedLine.AddValue(cmTrimWhitespace(value)); return true; } @@ -589,18 +590,17 @@ bool cmVisualStudioSlnParser::ParseTag(const std::string& fullTag, { size_t idxLeftParen = fullTag.find('('); if (idxLeftParen == fullTag.npos) { - parsedLine.SetTag(cmSystemTools::TrimWhitespace(fullTag)); + parsedLine.SetTag(cmTrimWhitespace(fullTag)); return true; } - parsedLine.SetTag( - cmSystemTools::TrimWhitespace(fullTag.substr(0, idxLeftParen))); + parsedLine.SetTag(cmTrimWhitespace(fullTag.substr(0, idxLeftParen))); size_t idxRightParen = fullTag.rfind(')'); if (idxRightParen == fullTag.npos) { this->LastResult.SetError(ResultErrorInputStructure, state.GetCurrentLine()); return false; } - const std::string& arg = cmSystemTools::TrimWhitespace( + const std::string& arg = cmTrimWhitespace( fullTag.substr(idxLeftParen + 1, idxRightParen - idxLeftParen - 1)); if (arg.front() == '"') { if (arg.back() != '"') { @@ -617,7 +617,7 @@ bool cmVisualStudioSlnParser::ParseTag(const std::string& fullTag, bool cmVisualStudioSlnParser::ParseValue(const std::string& value, ParsedLine& parsedLine) { - const std::string& trimmed = cmSystemTools::TrimWhitespace(value); + const std::string& trimmed = cmTrimWhitespace(value); if (trimmed.empty()) parsedLine.AddValue(trimmed); else if (trimmed.front() == '"' && trimmed.back() == '"') diff --git a/Source/cmWhileCommand.cxx b/Source/cmWhileCommand.cxx index a01fa6f..a396852 100644 --- a/Source/cmWhileCommand.cxx +++ b/Source/cmWhileCommand.cxx @@ -2,18 +2,45 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmWhileCommand.h" +#include "cm_memory.hxx" +#include "cm_static_string_view.hxx" +#include "cm_string_view.hxx" + #include "cmConditionEvaluator.h" #include "cmExecutionStatus.h" #include "cmExpandedCommandArgument.h" +#include "cmFunctionBlocker.h" +#include "cmListFileCache.h" #include "cmMakefile.h" #include "cmMessageType.h" #include "cmSystemTools.h" -#include <memory> // IWYU pragma: keep +#include <string> +#include <utility> + +class cmWhileFunctionBlocker : public cmFunctionBlocker +{ +public: + cmWhileFunctionBlocker(cmMakefile* mf); + ~cmWhileFunctionBlocker() override; + + cm::string_view StartCommandName() const override { return "while"_s; } + cm::string_view EndCommandName() const override { return "endwhile"_s; } + + bool ArgumentsMatch(cmListFileFunction const& lff, + cmMakefile& mf) const override; + + bool Replay(std::vector<cmListFileFunction> functions, + cmExecutionStatus& inStatus) override; + + std::vector<cmListFileArgument> Args; + +private: + cmMakefile* Makefile; +}; cmWhileFunctionBlocker::cmWhileFunctionBlocker(cmMakefile* mf) : Makefile(mf) - , Depth(0) { this->Makefile->PushLoopBlock(); } @@ -23,122 +50,93 @@ cmWhileFunctionBlocker::~cmWhileFunctionBlocker() this->Makefile->PopLoopBlock(); } -bool cmWhileFunctionBlocker::IsFunctionBlocked(const cmListFileFunction& lff, - cmMakefile& mf, - cmExecutionStatus& inStatus) +bool cmWhileFunctionBlocker::ArgumentsMatch(cmListFileFunction const& lff, + cmMakefile&) const { - // at end of for each execute recorded commands - if (lff.Name.Lower == "while") { - // record the number of while commands past this one - this->Depth++; - } else if (lff.Name.Lower == "endwhile") { - // if this is the endwhile for this while loop then execute - if (!this->Depth) { - // Remove the function blocker for this scope or bail. - std::unique_ptr<cmFunctionBlocker> fb( - mf.RemoveFunctionBlocker(this, lff)); - if (!fb) { - return false; - } + return lff.Arguments.empty() || lff.Arguments == this->Args; +} - std::string errorString; - - std::vector<cmExpandedCommandArgument> expandedArguments; - mf.ExpandArguments(this->Args, expandedArguments); - MessageType messageType; - - cmListFileContext execContext = this->GetStartingContext(); - - cmCommandContext commandContext; - commandContext.Line = execContext.Line; - commandContext.Name = execContext.Name; - - cmConditionEvaluator conditionEvaluator(mf, this->GetStartingContext(), - mf.GetBacktrace(commandContext)); - - bool isTrue = - conditionEvaluator.IsTrue(expandedArguments, errorString, messageType); - - while (isTrue) { - if (!errorString.empty()) { - std::string err = "had incorrect arguments: "; - for (cmListFileArgument const& arg : this->Args) { - err += (arg.Delim ? "\"" : ""); - err += arg.Value; - err += (arg.Delim ? "\"" : ""); - err += " "; - } - err += "("; - err += errorString; - err += ")."; - mf.IssueMessage(messageType, err); - if (messageType == MessageType::FATAL_ERROR) { - cmSystemTools::SetFatalErrorOccured(); - return true; - } - } - - // Invoke all the functions that were collected in the block. - for (cmListFileFunction const& fn : this->Functions) { - cmExecutionStatus status; - mf.ExecuteCommand(fn, status); - if (status.GetReturnInvoked()) { - inStatus.SetReturnInvoked(); - return true; - } - if (status.GetBreakInvoked()) { - return true; - } - if (status.GetContinueInvoked()) { - break; - } - if (cmSystemTools::GetFatalErrorOccured()) { - return true; - } - } - expandedArguments.clear(); - mf.ExpandArguments(this->Args, expandedArguments); - isTrue = conditionEvaluator.IsTrue(expandedArguments, errorString, - messageType); - } - return true; - } - // decrement for each nested while that ends - this->Depth--; - } +bool cmWhileFunctionBlocker::Replay(std::vector<cmListFileFunction> functions, + cmExecutionStatus& inStatus) +{ + cmMakefile& mf = inStatus.GetMakefile(); + std::string errorString; - // record the command - this->Functions.push_back(lff); + std::vector<cmExpandedCommandArgument> expandedArguments; + mf.ExpandArguments(this->Args, expandedArguments); + MessageType messageType; - // always return true - return true; -} + cmListFileContext execContext = this->GetStartingContext(); -bool cmWhileFunctionBlocker::ShouldRemove(const cmListFileFunction& lff, - cmMakefile&) -{ - if (lff.Name.Lower == "endwhile") { - // if the endwhile has arguments, then make sure - // they match the arguments of the matching while - if (lff.Arguments.empty() || lff.Arguments == this->Args) { - return true; + cmCommandContext commandContext; + commandContext.Line = execContext.Line; + commandContext.Name = execContext.Name; + + cmConditionEvaluator conditionEvaluator(mf, this->GetStartingContext(), + mf.GetBacktrace(commandContext)); + + bool isTrue = + conditionEvaluator.IsTrue(expandedArguments, errorString, messageType); + + while (isTrue) { + if (!errorString.empty()) { + std::string err = "had incorrect arguments: "; + for (cmListFileArgument const& arg : this->Args) { + err += (arg.Delim ? "\"" : ""); + err += arg.Value; + err += (arg.Delim ? "\"" : ""); + err += " "; + } + err += "("; + err += errorString; + err += ")."; + mf.IssueMessage(messageType, err); + if (messageType == MessageType::FATAL_ERROR) { + cmSystemTools::SetFatalErrorOccured(); + return true; + } } + + // Invoke all the functions that were collected in the block. + for (cmListFileFunction const& fn : functions) { + cmExecutionStatus status(mf); + mf.ExecuteCommand(fn, status); + if (status.GetReturnInvoked()) { + inStatus.SetReturnInvoked(); + return true; + } + if (status.GetBreakInvoked()) { + return true; + } + if (status.GetContinueInvoked()) { + break; + } + if (cmSystemTools::GetFatalErrorOccured()) { + return true; + } + } + expandedArguments.clear(); + mf.ExpandArguments(this->Args, expandedArguments); + isTrue = + conditionEvaluator.IsTrue(expandedArguments, errorString, messageType); } - return false; + return true; } -bool cmWhileCommand::InvokeInitialPass( - const std::vector<cmListFileArgument>& args, cmExecutionStatus&) +bool cmWhileCommand(std::vector<cmListFileArgument> 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; } // create a function blocker - cmWhileFunctionBlocker* f = new cmWhileFunctionBlocker(this->Makefile); - f->Args = args; - this->Makefile->AddFunctionBlocker(f); - + { + cmMakefile& makefile = status.GetMakefile(); + auto fb = cm::make_unique<cmWhileFunctionBlocker>(&makefile); + fb->Args = args; + makefile.AddFunctionBlocker(std::move(fb)); + } return true; } diff --git a/Source/cmWhileCommand.h b/Source/cmWhileCommand.h index 6f6d405..beca652 100644 --- a/Source/cmWhileCommand.h +++ b/Source/cmWhileCommand.h @@ -5,58 +5,13 @@ #include "cmConfigure.h" // IWYU pragma: keep -#include <string> #include <vector> -#include "cmCommand.h" -#include "cmFunctionBlocker.h" -#include "cmListFileCache.h" - class cmExecutionStatus; -class cmMakefile; - -class cmWhileFunctionBlocker : public cmFunctionBlocker -{ -public: - cmWhileFunctionBlocker(cmMakefile* mf); - ~cmWhileFunctionBlocker() override; - bool IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile& mf, - cmExecutionStatus&) override; - bool ShouldRemove(const cmListFileFunction& lff, cmMakefile& mf) override; - - std::vector<cmListFileArgument> Args; - std::vector<cmListFileFunction> Functions; - -private: - cmMakefile* Makefile; - int Depth; -}; +struct cmListFileArgument; /// \brief Starts a while loop -class cmWhileCommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - cmCommand* Clone() override { return new cmWhileCommand; } - - /** - * This overrides the default InvokeInitialPass implementation. - * It records the arguments before expansion. - */ - bool InvokeInitialPass(const std::vector<cmListFileArgument>& args, - cmExecutionStatus&) override; - - /** - * This is called when the command is first encountered in - * the CMakeLists.txt file. - */ - bool InitialPass(std::vector<std::string> const&, - cmExecutionStatus&) override - { - return false; - } -}; +bool cmWhileCommand(std::vector<cmListFileArgument> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmWorkerPool.cxx b/Source/cmWorkerPool.cxx index cbf070e..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" @@ -16,6 +17,8 @@ #include <stddef.h> #include <thread> +#include "cm_memory.hxx" + /** * @brief libuv pipe buffer class */ @@ -304,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); } } @@ -330,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(); @@ -349,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/cmWorkerPool.h b/Source/cmWorkerPool.h index f08bb4f..d708118 100644 --- a/Source/cmWorkerPool.h +++ b/Source/cmWorkerPool.h @@ -5,14 +5,13 @@ #include "cmConfigure.h" // IWYU pragma: keep -#include "cmAlgorithms.h" // IWYU pragma: keep - -#include <memory> // IWYU pragma: keep #include <stdint.h> #include <string> #include <utility> #include <vector> +#include "cm_memory.hxx" + // -- Types class cmWorkerPoolInternal; 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 9028f84..3e0e043 100644 --- a/Source/cmWriteFileCommand.h +++ b/Source/cmWriteFileCommand.h @@ -8,28 +8,13 @@ #include <string> #include <vector> -#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. - */ - cmCommand* Clone() override { return new 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 c33bb7e..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; - cmSystemTools::ExpandListArgument(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; - cmSystemTools::ExpandListArgument(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_codecvt.hxx b/Source/cm_codecvt.hxx index 2df3961..2060584 100644 --- a/Source/cm_codecvt.hxx +++ b/Source/cm_codecvt.hxx @@ -18,7 +18,7 @@ public: ANSI }; -#ifdef CMAKE_BUILD_WITH_CMAKE +#ifndef CMAKE_BOOTSTRAP codecvt(Encoding e); diff --git a/Source/cm_memory.hxx b/Source/cm_memory.hxx new file mode 100644 index 0000000..9f5e678 --- /dev/null +++ b/Source/cm_memory.hxx @@ -0,0 +1,31 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#ifndef cm_memory_hxx +#define cm_memory_hxx + +#include "cmConfigure.h" // IWYU pragma: keep + +#include <memory> // IWYU pragma: export +#if !defined(CMake_HAVE_CXX_MAKE_UNIQUE) +# include <utility> +#endif + +namespace cm { + +#if defined(CMake_HAVE_CXX_MAKE_UNIQUE) + +using std::make_unique; + +#else + +template <typename T, typename... Args> +std::unique_ptr<T> make_unique(Args&&... args) +{ + return std::unique_ptr<T>(new T(std::forward<Args>(args)...)); +} + +#endif + +} // namespace cm + +#endif 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 3772f09..1746082 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -2,6 +2,8 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmake.h" +#include "cm_memory.hxx" + #include "cmAlgorithms.h" #include "cmCommands.h" #include "cmDocumentation.h" @@ -19,15 +21,17 @@ #include "cmMessenger.h" #include "cmState.h" #include "cmStateDirectory.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmTarget.h" #include "cmTargetLinkLibraryType.h" #include "cmUtils.hxx" #include "cmVersionConfig.h" #include "cmWorkingDirectory.h" +#include "cm_string_view.hxx" #include "cm_sys_stat.h" -#if defined(CMAKE_BUILD_WITH_CMAKE) +#if !defined(CMAKE_BOOTSTRAP) # include "cm_jsoncpp_writer.h" # include "cmFileAPI.h" @@ -36,11 +40,11 @@ # include <unordered_map> #endif -#if defined(CMAKE_BUILD_WITH_CMAKE) +#if !defined(CMAKE_BOOTSTRAP) # define CMAKE_USE_ECLIPSE #endif -#if defined(__MINGW32__) && !defined(CMAKE_BUILD_WITH_CMAKE) +#if defined(__MINGW32__) && defined(CMAKE_BOOTSTRAP) # define CMAKE_BOOT_MINGW #endif @@ -68,7 +72,7 @@ # include "cmGlobalWatcomWMakeGenerator.h" #endif #include "cmGlobalUnixMakefileGenerator3.h" -#if defined(CMAKE_BUILD_WITH_CMAKE) +#if !defined(CMAKE_BOOTSTRAP) # include "cmGlobalNinjaGenerator.h" #endif #include "cmExtraCodeLiteGenerator.h" @@ -88,7 +92,7 @@ #endif #if defined(__APPLE__) -# if defined(CMAKE_BUILD_WITH_CMAKE) +# if !defined(CMAKE_BOOTSTRAP) # include "cmGlobalXCodeGenerator.h" # define CMAKE_USE_XCODE 1 @@ -104,8 +108,6 @@ #include <cstring> #include <initializer_list> #include <iostream> -#include <iterator> -#include <memory> // IWYU pragma: keep #include <sstream> #include <stdio.h> #include <stdlib.h> @@ -113,7 +115,7 @@ namespace { -#if defined(CMAKE_BUILD_WITH_CMAKE) +#if !defined(CMAKE_BOOTSTRAP) typedef std::unordered_map<std::string, Json::Value> JsonValueMapType; #endif @@ -122,31 +124,25 @@ typedef std::unordered_map<std::string, Json::Value> JsonValueMapType; static bool cmakeCheckStampFile(const std::string& stampName); static bool cmakeCheckStampList(const std::string& stampList); -void cmWarnUnusedCliWarning(const std::string& variable, int /*unused*/, - void* ctx, const char* /*unused*/, - const cmMakefile* /*unused*/) +static void cmWarnUnusedCliWarning(const std::string& variable, int /*unused*/, + void* ctx, const char* /*unused*/, + const cmMakefile* /*unused*/) { cmake* cm = reinterpret_cast<cmake*>(ctx); cm->MarkCliAsUsed(variable); } cmake::cmake(Role role, cmState::Mode mode) + : FileTimeCache(cm::make_unique<cmFileTimeCache>()) +#ifndef CMAKE_BOOTSTRAP + , VariableWatch(cm::make_unique<cmVariableWatch>()) +#endif + , State(cm::make_unique<cmState>()) + , Messenger(cm::make_unique<cmMessenger>()) { - this->Trace = false; - this->TraceExpand = false; - this->WarnUninitialized = false; - this->WarnUnused = false; - this->WarnUnusedCli = true; - this->CheckSystemVars = false; - this->DebugOutput = false; - this->DebugTryCompile = false; - this->ClearBuildSystem = false; - this->FileTimeCache = new cmFileTimeCache; - - this->State = new cmState; + this->TraceFile.close(); this->State->SetMode(mode); this->CurrentSnapshot = this->State->CreateBaseSnapshot(); - this->Messenger = new cmMessenger; #ifdef __APPLE__ struct rlimit rlp; @@ -158,16 +154,6 @@ cmake::cmake(Role role, cmState::Mode mode) } #endif - this->GlobalGenerator = nullptr; - this->GeneratorInstanceSet = false; - this->GeneratorPlatformSet = false; - this->GeneratorToolsetSet = false; - this->CurrentWorkingMode = NORMAL_MODE; - -#ifdef CMAKE_BUILD_WITH_CMAKE - this->VariableWatch = new cmVariableWatch; -#endif - this->AddDefaultGenerators(); this->AddDefaultExtraGenerators(); if (role == RoleScript || role == RoleProject) { @@ -184,58 +170,41 @@ cmake::cmake(Role role, cmState::Mode mode) // Make sure we can capture the build tool output. cmSystemTools::EnableVSConsoleOutput(); - // Set up a list of source and header extensions - // these are used to find files when the extension - // is not given - // The "c" extension MUST precede the "C" extension. - this->SourceFileExtensions.emplace_back("c"); - this->SourceFileExtensions.emplace_back("C"); - - this->SourceFileExtensions.emplace_back("c++"); - this->SourceFileExtensions.emplace_back("cc"); - this->SourceFileExtensions.emplace_back("cpp"); - this->SourceFileExtensions.emplace_back("cxx"); - this->SourceFileExtensions.emplace_back("cu"); - this->SourceFileExtensions.emplace_back("m"); - this->SourceFileExtensions.emplace_back("M"); - this->SourceFileExtensions.emplace_back("mm"); - - std::copy(this->SourceFileExtensions.begin(), - this->SourceFileExtensions.end(), - std::inserter(this->SourceFileExtensionsSet, - this->SourceFileExtensionsSet.end())); - - this->HeaderFileExtensions.emplace_back("h"); - this->HeaderFileExtensions.emplace_back("hh"); - this->HeaderFileExtensions.emplace_back("h++"); - this->HeaderFileExtensions.emplace_back("hm"); - this->HeaderFileExtensions.emplace_back("hpp"); - this->HeaderFileExtensions.emplace_back("hxx"); - this->HeaderFileExtensions.emplace_back("in"); - this->HeaderFileExtensions.emplace_back("txx"); - - std::copy(this->HeaderFileExtensions.begin(), - this->HeaderFileExtensions.end(), - std::inserter(this->HeaderFileExtensionsSet, - this->HeaderFileExtensionsSet.end())); + // Set up a list of source and header extensions. + // These are used to find files when the extension is not given. + { + auto setupExts = [](FileExtensions& exts, + std::initializer_list<cm::string_view> extList) { + // Fill ordered vector + exts.ordered.reserve(extList.size()); + for (cm::string_view ext : extList) { + exts.ordered.emplace_back(ext); + }; + // Fill unordered set + exts.unordered.insert(exts.ordered.begin(), exts.ordered.end()); + }; + + // The "c" extension MUST precede the "C" extension. + setupExts(this->SourceFileExtensions, + { "c", "C", "c++", "cc", "cpp", "cxx", "cu", "m", "M", "mm" }); + setupExts(this->HeaderFileExtensions, + { "h", "hh", "h++", "hm", "hpp", "hxx", "in", "txx" }); + setupExts(this->CudaFileExtensions, { "cu" }); + setupExts(this->FortranFileExtensions, + { "f", "F", "for", "f77", "f90", "f95", "f03" }); + } } cmake::~cmake() { - delete this->State; - delete this->Messenger; if (this->GlobalGenerator) { delete this->GlobalGenerator; this->GlobalGenerator = nullptr; } cmDeleteAll(this->Generators); -#ifdef CMAKE_BUILD_WITH_CMAKE - delete this->VariableWatch; -#endif - delete this->FileTimeCache; } -#if defined(CMAKE_BUILD_WITH_CMAKE) +#if !defined(CMAKE_BOOTSTRAP) Json::Value cmake::ReportVersionJson() const { Json::Value version = Json::objectValue; @@ -294,7 +263,7 @@ Json::Value cmake::ReportCapabilitiesJson() const std::string cmake::ReportCapabilities() const { std::string result; -#if defined(CMAKE_BUILD_WITH_CMAKE) +#if !defined(CMAKE_BOOTSTRAP) Json::FastWriter writer; result = writer.write(this->ReportCapabilitiesJson()); #else @@ -327,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 @@ -460,7 +430,12 @@ bool cmake::SetCacheArgs(const std::vector<std::string>& args) return false; } // Register fake project commands that hint misuse in script mode. - GetProjectCommandsInScriptMode(this->State); + 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; @@ -490,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) { @@ -511,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 @@ -561,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; - cmSystemTools::ExpandListArgument(includes, includeDirs); + std::vector<std::string> includeDirs = cmExpandedList(includes); gg->CreateGenerationObjects(); cmLocalGenerator* lg = gg->LocalGenerators[0]; @@ -578,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; - cmSystemTools::ExpandListArgument(libs, libList); + std::vector<std::string> libList = cmExpandedList(libs); for (std::string const& lib : libList) { tgt->AddLinkLibrary(*mf, lib, GENERAL_LibraryType); } @@ -629,16 +594,15 @@ void cmake::LoadEnvironmentPresets() this->EnvironmentGenerator = envGenVar; } - auto readGeneratorVar = [&](std::string name, std::string& key) { + auto readGeneratorVar = [&](std::string const& name, std::string& key) { std::string varValue; if (cmSystemTools::GetEnv(name, varValue)) { 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"); } } @@ -772,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); @@ -840,8 +809,8 @@ void cmake::SetArgs(const std::vector<std::string>& args) kdevError = "\nThe KDevelop3 generator is not supported anymore."; } - cmSystemTools::Error("Could not create named generator " + value + - kdevError); + cmSystemTools::Error( + cmStrCat("Could not create named generator ", value, kdevError)); this->PrintGeneratorList(); return; } @@ -902,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 @@ -912,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; } @@ -1000,7 +981,7 @@ int cmake::AddCMakePaths() this->AddCacheEntry("CMAKE_COMMAND", cmSystemTools::GetCMakeCommand().c_str(), "Path to CMake executable.", cmStateEnums::INTERNAL); -#ifdef CMAKE_BUILD_WITH_CMAKE +#ifndef CMAKE_BOOTSTRAP this->AddCacheEntry( "CMAKE_CTEST_COMMAND", cmSystemTools::GetCTestCommand().c_str(), "Path to ctest program executable.", cmStateEnums::INTERNAL); @@ -1026,7 +1007,7 @@ int cmake::AddCMakePaths() void cmake::AddDefaultExtraGenerators() { -#if defined(CMAKE_BUILD_WITH_CMAKE) +#if !defined(CMAKE_BOOTSTRAP) this->ExtraGenerators.push_back(cmExtraCodeBlocksGenerator::GetFactory()); this->ExtraGenerators.push_back(cmExtraCodeLiteGenerator::GetFactory()); this->ExtraGenerators.push_back(cmExtraSublimeTextGenerator::GetFactory()); @@ -1170,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", @@ -1230,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())) { @@ -1253,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; } @@ -1282,8 +1259,7 @@ struct SaveCacheEntry int cmake::HandleDeleteCacheVariables(const std::string& var) { - std::vector<std::string> argsSplit; - cmSystemTools::ExpandListArgument(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()) { @@ -1397,18 +1373,16 @@ int cmake::Configure() // so we cannot rely on command line options alone. Always ensure our // messenger is in sync with the cache. const char* value = this->State->GetCacheEntryValue("CMAKE_WARN_DEPRECATED"); - this->Messenger->SetSuppressDeprecatedWarnings(value && - cmSystemTools::IsOff(value)); + this->Messenger->SetSuppressDeprecatedWarnings(value && cmIsOff(value)); value = this->State->GetCacheEntryValue("CMAKE_ERROR_DEPRECATED"); - this->Messenger->SetDeprecatedWarningsAsErrors(cmSystemTools::IsOn(value)); + this->Messenger->SetDeprecatedWarningsAsErrors(cmIsOn(value)); value = this->State->GetCacheEntryValue("CMAKE_SUPPRESS_DEVELOPER_WARNINGS"); - this->Messenger->SetSuppressDevWarnings(cmSystemTools::IsOn(value)); + this->Messenger->SetSuppressDevWarnings(cmIsOn(value)); value = this->State->GetCacheEntryValue("CMAKE_SUPPRESS_DEVELOPER_ERRORS"); - this->Messenger->SetDevWarningsAsErrors(value && - cmSystemTools::IsOff(value)); + this->Messenger->SetDevWarningsAsErrors(value && cmIsOff(value)); int ret = this->ActualConfigure(); const char* delCacheVars = @@ -1468,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; } @@ -1491,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; } @@ -1510,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; } @@ -1528,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; } @@ -1553,7 +1523,7 @@ int cmake::ActualConfigure() this->TruncateOutputLog("CMakeError.log"); } -#if defined(CMAKE_BUILD_WITH_CMAKE) +#if !defined(CMAKE_BOOTSTRAP) this->FileAPI = cm::make_unique<cmFileAPI>(this); this->FileAPI->ReadQueries(); #endif @@ -1791,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; } @@ -1821,7 +1791,7 @@ int cmake::Generate() // for the Visual Studio and Xcode generators.) this->SaveCache(this->GetHomeOutputDirectory()); -#if defined(CMAKE_BUILD_WITH_CMAKE) +#if !defined(CMAKE_BOOTSTRAP) this->FileAPI->WriteReplies(); #endif @@ -1836,15 +1806,13 @@ void cmake::AddCacheEntry(const std::string& key, const char* value, this->UnwatchUnusedCli(key); if (key == "CMAKE_WARN_DEPRECATED") { - this->Messenger->SetSuppressDeprecatedWarnings( - value && cmSystemTools::IsOff(value)); + this->Messenger->SetSuppressDeprecatedWarnings(value && cmIsOff(value)); } else if (key == "CMAKE_ERROR_DEPRECATED") { - this->Messenger->SetDeprecatedWarningsAsErrors(cmSystemTools::IsOn(value)); + this->Messenger->SetDeprecatedWarningsAsErrors(cmIsOn(value)); } else if (key == "CMAKE_SUPPRESS_DEVELOPER_WARNINGS") { - this->Messenger->SetSuppressDevWarnings(cmSystemTools::IsOn(value)); + this->Messenger->SetSuppressDevWarnings(cmIsOn(value)); } else if (key == "CMAKE_SUPPRESS_DEVELOPER_ERRORS") { - this->Messenger->SetDevWarningsAsErrors(value && - cmSystemTools::IsOff(value)); + this->Messenger->SetDevWarningsAsErrors(value && cmIsOff(value)); } } @@ -1898,12 +1866,12 @@ const char* cmake::GetCacheDefinition(const std::string& name) const void cmake::AddScriptingCommands() { - GetScriptingCommands(this->State); + GetScriptingCommands(this->GetState()); } void cmake::AddProjectCommands() { - GetProjectCommands(this->State); + GetProjectCommands(this->GetState()); } void cmake::AddDefaultGenerators() @@ -1927,7 +1895,7 @@ void cmake::AddDefaultGenerators() this->Generators.push_back(cmGlobalMinGWMakefileGenerator::NewFactory()); #endif this->Generators.push_back(cmGlobalUnixMakefileGenerator3::NewFactory()); -#if defined(CMAKE_BUILD_WITH_CMAKE) +#if !defined(CMAKE_BOOTSTRAP) # if defined(__linux__) || defined(_WIN32) this->Generators.push_back(cmGlobalGhsMultiGenerator::NewFactory()); # endif @@ -1953,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 " @@ -2040,8 +2008,7 @@ void cmake::AppendGlobalGeneratorsDocumentation( for (cmGlobalGeneratorFactory* g : this->Generators) { cmDocumentationEntry e; g->GetDocumentation(e); - if (!foundDefaultOne && - cmSystemTools::StringStartsWith(e.Name, defaultName.c_str())) { + if (!foundDefaultOne && cmHasPrefix(e.Name, defaultName)) { e.CustomNamePrefix = '*'; foundDefaultOne = true; } @@ -2087,7 +2054,7 @@ std::vector<cmDocumentationEntry> cmake::GetGeneratorsDocumentation() void cmake::PrintGeneratorList() { -#ifdef CMAKE_BUILD_WITH_CMAKE +#ifndef CMAKE_BOOTSTRAP cmDocumentation doc; auto generators = this->GetGeneratorsDocumentation(); doc.AppendSection("Generators", generators); @@ -2109,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; @@ -2132,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; } @@ -2192,7 +2158,7 @@ int cmake::CheckBuildSystem() // If any byproduct of makefile generation is missing we must re-run. std::vector<std::string> products; if (const char* productStr = mf.GetDefinition("CMAKE_MAKEFILE_PRODUCTS")) { - cmSystemTools::ExpandListArgument(productStr, products); + cmExpandList(productStr, products); } for (std::string const& p : products) { if (!(cmSystemTools::FileExists(p) || cmSystemTools::FileIsSymlink(p))) { @@ -2211,16 +2177,14 @@ int cmake::CheckBuildSystem() const char* dependsStr = mf.GetDefinition("CMAKE_MAKEFILE_DEPENDS"); const char* outputsStr = mf.GetDefinition("CMAKE_MAKEFILE_OUTPUTS"); if (dependsStr && outputsStr) { - cmSystemTools::ExpandListArgument(dependsStr, depends); - cmSystemTools::ExpandListArgument(outputsStr, outputs); + cmExpandList(dependsStr, depends); + cmExpandList(outputsStr, outputs); } 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; } @@ -2236,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; } @@ -2255,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; } @@ -2284,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; @@ -2303,14 +2263,6 @@ void cmake::TruncateOutputLog(const char* fname) } } -inline std::string removeQuotes(const std::string& s) -{ - if (s.front() == '\"' && s.back() == '\"') { - return s.substr(1, s.size() - 2); - } - return s; -} - void cmake::MarkCliAsUsed(const std::string& variable) { this->UsedCliVariables[variable] = true; @@ -2318,13 +2270,13 @@ void cmake::MarkCliAsUsed(const std::string& variable) void cmake::GenerateGraphViz(const std::string& fileName) const { -#ifdef CMAKE_BUILD_WITH_CMAKE +#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); @@ -2421,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; @@ -2431,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)) { @@ -2447,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"); } { @@ -2504,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 @@ -2596,7 +2543,7 @@ std::vector<std::string> cmake::GetDebugConfigs() if (const char* config_list = this->State->GetGlobalProperty("DEBUG_CONFIGURATIONS")) { // Expand the specified list and convert to upper-case. - cmSystemTools::ExpandListArgument(config_list, configs); + cmExpandList(config_list, configs); std::transform(configs.begin(), configs.end(), configs.begin(), cmSystemTools::UpperCase); } @@ -2607,11 +2554,6 @@ std::vector<std::string> cmake::GetDebugConfigs() return configs; } -cmMessenger* cmake::GetMessenger() const -{ - return this->Messenger; -} - int cmake::Build(int jobs, const std::string& dir, const std::vector<std::string>& targets, const std::string& config, @@ -2672,7 +2614,7 @@ int cmake::Build(int jobs, const std::string& dir, const char* cachedVerbose = this->State->GetCacheEntryValue("CMAKE_VERBOSE_MAKEFILE"); - if (cmSystemTools::IsOn(cachedVerbose)) { + if (cmIsOn(cachedVerbose)) { verbose = true; } @@ -2720,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. @@ -2782,9 +2724,9 @@ bool cmake::Open(const std::string& dir, bool dryRun) void cmake::WatchUnusedCli(const std::string& var) { -#ifdef CMAKE_BUILD_WITH_CMAKE +#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 @@ -2792,7 +2734,7 @@ void cmake::WatchUnusedCli(const std::string& var) void cmake::UnwatchUnusedCli(const std::string& var) { -#ifdef CMAKE_BUILD_WITH_CMAKE +#ifndef CMAKE_BOOTSTRAP this->VariableWatch->RemoveWatch(var, cmWarnUnusedCliWarning); this->UsedCliVariables.erase(var); #endif @@ -2800,7 +2742,7 @@ void cmake::UnwatchUnusedCli(const std::string& var) void cmake::RunCheckForUnusedVariables() { -#ifdef CMAKE_BUILD_WITH_CMAKE +#ifndef CMAKE_BOOTSTRAP bool haveUnused = false; std::ostringstream msg; msg << "Manually-specified variables were not used by the project:"; diff --git a/Source/cmake.h b/Source/cmake.h index fa4409a..081e120 100644 --- a/Source/cmake.h +++ b/Source/cmake.h @@ -7,12 +7,13 @@ #include <functional> #include <map> -#include <memory> // IWYU pragma: keep +#include <memory> #include <set> #include <string> #include <unordered_set> #include <vector> +#include "cmGeneratedFileStream.h" #include "cmInstalledFile.h" #include "cmListFileCache.h" #include "cmMessageType.h" @@ -20,7 +21,7 @@ #include "cmStateSnapshot.h" #include "cmStateTypes.h" -#if defined(CMAKE_BUILD_WITH_CMAKE) +#if !defined(CMAKE_BOOTSTRAP) # include "cm_jsoncpp_value.h" #endif @@ -121,6 +122,17 @@ public: bool isAlias; }; + struct FileExtensions + { + bool Test(std::string const& ext) const + { + return (this->unordered.find(ext) != this->unordered.end()); + } + + std::vector<std::string> ordered; + std::unordered_set<std::string> unordered; + }; + typedef std::map<std::string, cmInstalledFile> InstalledFilesMap; static const int NO_BUILD_PARALLEL_LEVEL = -1; @@ -134,7 +146,7 @@ public: cmake(cmake const&) = delete; cmake& operator=(cmake const&) = delete; -#if defined(CMAKE_BUILD_WITH_CMAKE) +#if !defined(CMAKE_BOOTSTRAP) Json::Value ReportVersionJson() const; Json::Value ReportCapabilitiesJson() const; #endif @@ -233,24 +245,42 @@ public: const std::vector<std::string>& GetSourceExtensions() const { - return this->SourceFileExtensions; + return this->SourceFileExtensions.ordered; } bool IsSourceExtension(const std::string& ext) const { - return this->SourceFileExtensionsSet.find(ext) != - this->SourceFileExtensionsSet.end(); + return this->SourceFileExtensions.Test(ext); } const std::vector<std::string>& GetHeaderExtensions() const { - return this->HeaderFileExtensions; + return this->HeaderFileExtensions.ordered; } bool IsHeaderExtension(const std::string& ext) const { - return this->HeaderFileExtensionsSet.find(ext) != - this->HeaderFileExtensionsSet.end(); + return this->HeaderFileExtensions.Test(ext); + } + + const std::vector<std::string>& GetCudaExtensions() const + { + return this->CudaFileExtensions.ordered; + } + + bool IsCudaExtension(const std::string& ext) const + { + return this->CudaFileExtensions.Test(ext); + } + + const std::vector<std::string>& GetFortranExtensions() const + { + return this->FortranFileExtensions.ordered; + } + + bool IsFortranExtension(const std::string& ext) const + { + return this->FortranFileExtensions.Test(ext); } // Strips the extension (if present and known) from a filename @@ -305,9 +335,9 @@ public: //! this is called by generators to update the progress void UpdateProgress(const std::string& msg, float prog); -#if defined(CMAKE_BUILD_WITH_CMAKE) +#if !defined(CMAKE_BOOTSTRAP) //! Get the variable watch object - cmVariableWatch* GetVariableWatch() { return this->VariableWatch; } + cmVariableWatch* GetVariableWatch() { return this->VariableWatch.get(); } #endif std::vector<cmDocumentationEntry> GetGeneratorsDocumentation(); @@ -348,18 +378,18 @@ public: /** * Get the file comparison class */ - cmFileTimeCache* GetFileTimeCache() { return this->FileTimeCache; } + cmFileTimeCache* GetFileTimeCache() { return this->FileTimeCache.get(); } - // Get the selected log level for `message()` commands during the cmake run. + //! Get the selected log level for `message()` commands during the cmake run. LogLevel GetLogLevel() const { return this->MessageLogLevel; } void SetLogLevel(LogLevel level) { this->MessageLogLevel = level; } static LogLevel StringToLogLevel(const std::string& levelStr); - // Do we want debug output during the cmake run. + //! Do we want debug output during the cmake run. bool GetDebugOutput() { return this->DebugOutput; } void SetDebugOutputOn(bool b) { this->DebugOutput = b; } - // Do we want trace output during the cmake run. + //! Do we want trace output during the cmake run. bool GetTrace() { return this->Trace; } void SetTrace(bool b) { this->Trace = b; } bool GetTraceExpand() { return this->TraceExpand; } @@ -372,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; } @@ -396,31 +429,31 @@ public: return this->CMakeEditCommand; } - cmMessenger* GetMessenger() const; + cmMessenger* GetMessenger() const { return this->Messenger.get(); } - /* + /** * Get the state of the suppression of developer (author) warnings. * Returns false, by default, if developer warnings should be shown, true * otherwise. */ bool GetSuppressDevWarnings() const; - /* + /** * Set the state of the suppression of developer (author) warnings. */ void SetSuppressDevWarnings(bool v); - /* + /** * Get the state of the suppression of deprecated warnings. * Returns false, by default, if deprecated warnings should be shown, true * otherwise. */ bool GetSuppressDeprecatedWarnings() const; - /* + /** * Set the state of the suppression of deprecated warnings. */ void SetSuppressDeprecatedWarnings(bool v); - /* + /** * Get the state of treating developer (author) warnings as errors. * Returns false, by default, if warnings should not be treated as errors, * true otherwise. @@ -431,7 +464,7 @@ public: */ void SetDevWarningsAsErrors(bool v); - /* + /** * Get the state of treating deprecated warnings as errors. * Returns false, by default, if warnings should not be treated as errors, * true otherwise. @@ -459,7 +492,7 @@ public: void UnwatchUnusedCli(const std::string& var); void WatchUnusedCli(const std::string& var); - cmState* GetState() const { return this->State; } + cmState* GetState() const { return this->State.get(); } void SetCurrentSnapshot(cmStateSnapshot const& snapshot) { this->CurrentSnapshot = snapshot; @@ -480,14 +513,14 @@ protected: void AddDefaultGenerators(); void AddDefaultExtraGenerators(); - cmGlobalGenerator* GlobalGenerator; + cmGlobalGenerator* GlobalGenerator = nullptr; std::map<std::string, DiagLevel> DiagLevels; std::string GeneratorInstance; std::string GeneratorPlatform; std::string GeneratorToolset; - bool GeneratorInstanceSet; - bool GeneratorPlatformSet; - bool GeneratorToolsetSet; + bool GeneratorInstanceSet = false; + bool GeneratorPlatformSet = false; + bool GeneratorToolsetSet = false; //! read in a cmake list file to initialize the cache void ReadListFile(const std::vector<std::string>& args, @@ -514,14 +547,15 @@ protected: private: ProgressCallbackType ProgressCallback; - WorkingMode CurrentWorkingMode; - bool DebugOutput; - bool Trace; - bool TraceExpand; - bool WarnUninitialized; - bool WarnUnused; - bool WarnUnusedCli; - bool CheckSystemVars; + WorkingMode CurrentWorkingMode = NORMAL_MODE; + bool DebugOutput = false; + bool Trace = false; + bool TraceExpand = false; + cmGeneratedFileStream TraceFile; + bool WarnUninitialized = false; + bool WarnUnused = false; + bool WarnUnusedCli = true; + bool CheckSystemVars = false; std::map<std::string, bool> UsedCliVariables; std::string CMakeEditCommand; std::string CXXEnvironment; @@ -531,24 +565,24 @@ private: std::string CheckStampList; std::string VSSolutionFile; std::string EnvironmentGenerator; - std::vector<std::string> SourceFileExtensions; - std::unordered_set<std::string> SourceFileExtensionsSet; - std::vector<std::string> HeaderFileExtensions; - std::unordered_set<std::string> HeaderFileExtensionsSet; - bool ClearBuildSystem; - bool DebugTryCompile; - cmFileTimeCache* FileTimeCache; + FileExtensions SourceFileExtensions; + FileExtensions HeaderFileExtensions; + FileExtensions CudaFileExtensions; + FileExtensions FortranFileExtensions; + bool ClearBuildSystem = false; + bool DebugTryCompile = false; + std::unique_ptr<cmFileTimeCache> FileTimeCache; std::string GraphVizFile; InstalledFilesMap InstalledFiles; -#if defined(CMAKE_BUILD_WITH_CMAKE) - cmVariableWatch* VariableWatch; +#if !defined(CMAKE_BOOTSTRAP) + std::unique_ptr<cmVariableWatch> VariableWatch; std::unique_ptr<cmFileAPI> FileAPI; #endif - cmState* State; + std::unique_ptr<cmState> State; cmStateSnapshot CurrentSnapshot; - cmMessenger* Messenger; + std::unique_ptr<cmMessenger> Messenger; std::vector<std::string> TraceOnlyThisSources; @@ -556,7 +590,7 @@ private: void UpdateConversionPathTable(); - // Print a list of valid generators to stderr. + //! Print a list of valid generators to stderr. void PrintGeneratorList(); std::unique_ptr<cmGlobalGenerator> EvaluateDefaultGlobalGenerator(); diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx index a6348b3..2b51a2a 100644 --- a/Source/cmakemain.cxx +++ b/Source/cmakemain.cxx @@ -7,11 +7,12 @@ #include "cmMakefile.h" #include "cmState.h" #include "cmStateTypes.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmake.h" #include "cmcmd.h" -#ifdef CMAKE_BUILD_WITH_CMAKE +#ifndef CMAKE_BOOTSTRAP # include "cmDocumentation.h" # include "cmDynamicLoader.h" #endif @@ -19,7 +20,7 @@ #include "cm_uv.h" #include "cmsys/Encoding.hxx" -#if defined(_WIN32) && defined(CMAKE_BUILD_WITH_CMAKE) +#if defined(_WIN32) && !defined(CMAKE_BOOTSTRAP) # include "cmsys/ConsoleBuf.hxx" #endif @@ -31,13 +32,14 @@ #include <string> #include <vector> -#ifdef CMAKE_BUILD_WITH_CMAKE -static const char* cmDocumentationName[][2] = { +namespace { +#ifndef CMAKE_BOOTSTRAP +const char* cmDocumentationName[][2] = { { nullptr, " cmake - Cross-Platform Makefile Generator." }, { nullptr, nullptr } }; -static const char* cmDocumentationUsage[][2] = { +const char* cmDocumentationUsage[][2] = { { nullptr, " cmake [options] <path-to-source>\n" " cmake [options] <path-to-existing-build>\n" @@ -49,40 +51,12 @@ static const char* cmDocumentationUsage[][2] = { { nullptr, nullptr } }; -static const char* cmDocumentationUsageNote[][2] = { +const char* cmDocumentationUsageNote[][2] = { { nullptr, "Run 'cmake --help' for more information." }, { nullptr, nullptr } }; -# define CMAKE_BUILD_OPTIONS \ - " <dir> = Project binary directory to be built.\n" \ - " --parallel [<jobs>], -j [<jobs>]\n" \ - " = Build in parallel using the given number of jobs. \n" \ - " If <jobs> is omitted the native build tool's \n" \ - " default number is used.\n" \ - " The CMAKE_BUILD_PARALLEL_LEVEL environment " \ - "variable\n" \ - " specifies a default parallel level when this " \ - "option\n" \ - " is not given.\n" \ - " --target <tgt>..., -t <tgt>... \n" \ - " = Build <tgt> instead of default targets.\n" \ - " --config <cfg> = For multi-configuration tools, choose <cfg>.\n" \ - " --clean-first = Build target 'clean' first, then build.\n" \ - " (To clean only, use --target 'clean'.)\n" \ - " --verbose, -v = Enable verbose output - if supported - including\n" \ - " the build commands to be executed. \n" \ - " -- = Pass remaining options to the native tool.\n" - -# define CMAKE_INSTALL_OPTIONS \ - " <dir> = Project binary directory to install.\n" \ - " --config <cfg> = For multi-configuration tools, choose <cfg>.\n" \ - " --component <comp> = Component-based install. Only install <comp>.\n" \ - " --prefix <prefix> = The installation prefix CMAKE_INSTALL_PREFIX.\n" \ - " --strip = Performing install/strip.\n" \ - " -v --verbose = Enable verbose output.\n" - -static const char* cmDocumentationOptions[][2] = { +const char* cmDocumentationOptions[][2] = { CMAKE_STANDARD_OPTIONS_TABLE, { "-E", "CMake command mode." }, { "-L[A][H]", "List non-advanced cached variables." }, @@ -106,6 +80,8 @@ static 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." }, @@ -117,7 +93,7 @@ static const char* cmDocumentationOptions[][2] = { #endif -static int do_command(int ac, char const* const* av) +int do_command(int ac, char const* const* av) { std::vector<std::string> args; args.reserve(ac - 1); @@ -126,12 +102,7 @@ static int do_command(int ac, char const* const* av) return cmcmd::ExecuteCMakeCommand(args); } -int do_cmake(int ac, char const* const* av); -static int do_build(int ac, char const* const* av); -static int do_install(int ac, char const* const* av); -static int do_open(int ac, char const* const* av); - -static cmMakefile* cmakemainGetMakefile(cmake* cm) +cmMakefile* cmakemainGetMakefile(cmake* cm) { if (cm && cm->GetDebugOutput()) { cmGlobalGenerator* gg = cm->GetGlobalGenerator(); @@ -142,7 +113,7 @@ static cmMakefile* cmakemainGetMakefile(cmake* cm) return nullptr; } -static std::string cmakemainGetStack(cmake* cm) +std::string cmakemainGetStack(cmake* cm) { std::string msg; cmMakefile* mf = cmakemainGetMakefile(cm); @@ -156,70 +127,25 @@ static std::string cmakemainGetStack(cmake* cm) return msg; } -static void cmakemainMessageCallback(const std::string& m, - const char* /*unused*/, cmake* cm) +void cmakemainMessageCallback(const std::string& m, const char* /*unused*/, + cmake* cm) { - std::cerr << m << cmakemainGetStack(cm) << std::endl << std::flush; + std::cerr << m << cmakemainGetStack(cm) << std::endl; } -static void cmakemainProgressCallback(const std::string& m, float prog, - cmake* cm) +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())) { std::cout << "-- " << m << dir << cmakemainGetStack(cm) << std::endl; } - - std::cout.flush(); -} - -int main(int ac, char const* const* av) -{ - cmSystemTools::EnsureStdPipes(); -#if defined(_WIN32) && defined(CMAKE_BUILD_WITH_CMAKE) - // Replace streambuf so we can output Unicode to console - cmsys::ConsoleBuf::Manager consoleOut(std::cout); - consoleOut.SetUTF8Pipes(); - cmsys::ConsoleBuf::Manager consoleErr(std::cerr, true); - consoleErr.SetUTF8Pipes(); -#endif - cmsys::Encoding::CommandLineArguments args = - cmsys::Encoding::CommandLineArguments::Main(ac, av); - ac = args.argc(); - av = args.argv(); - - cmSystemTools::EnableMSVCDebugHook(); - cmSystemTools::InitializeLibUV(); - cmSystemTools::FindCMakeResources(av[0]); - if (ac > 1) { - if (strcmp(av[1], "--build") == 0) { - return do_build(ac, av); - } - if (strcmp(av[1], "--install") == 0) { - return do_install(ac, av); - } - if (strcmp(av[1], "--open") == 0) { - return do_open(ac, av); - } - if (strcmp(av[1], "-E") == 0) { - return do_command(ac, av); - } - } - int ret = do_cmake(ac, av); -#ifdef CMAKE_BUILD_WITH_CMAKE - cmDynamicLoader::FlushCache(); -#endif - uv_loop_close(uv_default_loop()); - return ret; } int do_cmake(int ac, char const* const* av) @@ -230,7 +156,7 @@ int do_cmake(int ac, char const* const* av) return 1; } -#ifdef CMAKE_BUILD_WITH_CMAKE +#ifndef CMAKE_BOOTSTRAP cmDocumentation doc; doc.addCMakeStandardDocSections(); if (doc.CheckOptions(ac, av)) { @@ -381,7 +307,6 @@ int do_cmake(int ac, char const* const* av) return 0; } -namespace { int extract_job_number(int& index, char const* current, char const* next, int len_of_flag) { @@ -396,7 +321,7 @@ int extract_job_number(int& index, char const* current, char const* next, unsigned long numJobs = 0; if (jobString.empty()) { jobs = cmake::DEFAULT_BUILD_PARALLEL_LEVEL; - } else if (cmSystemTools::StringToULong(jobString.c_str(), &numJobs)) { + } else if (cmStrToULong(jobString, &numJobs)) { if (numJobs == 0) { std::cerr << "The <jobs> value requires a positive integer argument.\n\n"; @@ -411,11 +336,10 @@ int extract_job_number(int& index, char const* current, char const* next, } return jobs; } -} -static int do_build(int ac, char const* const* av) +int do_build(int ac, char const* const* av) { -#ifndef CMAKE_BUILD_WITH_CMAKE +#ifdef CMAKE_BOOTSTRAP std::cerr << "This cmake does not support --build\n"; return -1; #else @@ -515,7 +439,7 @@ static int do_build(int ac, char const* const* av) jobs = cmake::DEFAULT_BUILD_PARALLEL_LEVEL; } else { unsigned long numJobs = 0; - if (cmSystemTools::StringToULong(parallel.c_str(), &numJobs)) { + if (cmStrToULong(parallel, &numJobs)) { if (numJobs == 0) { std::cerr << "The CMAKE_BUILD_PARALLEL_LEVEL environment variable " "requires a positive integer argument.\n\n"; @@ -541,7 +465,24 @@ static int do_build(int ac, char const* const* av) std::cerr << "Usage: cmake --build <dir> [options] [-- [native-options]]\n" "Options:\n" - CMAKE_BUILD_OPTIONS + " <dir> = Project binary directory to be built.\n" + " --parallel [<jobs>], -j [<jobs>]\n" + " = Build in parallel using the given number of jobs. \n" + " If <jobs> is omitted the native build tool's \n" + " default number is used.\n" + " The CMAKE_BUILD_PARALLEL_LEVEL environment " + "variable\n" + " specifies a default parallel level when this " + "option\n" + " is not given.\n" + " --target <tgt>..., -t <tgt>... \n" + " = Build <tgt> instead of default targets.\n" + " --config <cfg> = For multi-configuration tools, choose <cfg>.\n" + " --clean-first = Build target 'clean' first, then build.\n" + " (To clean only, use --target 'clean'.)\n" + " --verbose, -v = Enable verbose output - if supported - including\n" + " the build commands to be executed. \n" + " -- = Pass remaining options to the native tool.\n" ; /* clang-format on */ return 1; @@ -560,9 +501,9 @@ static int do_build(int ac, char const* const* av) #endif } -static int do_install(int ac, char const* const* av) +int do_install(int ac, char const* const* av) { -#ifndef CMAKE_BUILD_WITH_CMAKE +#ifdef CMAKE_BOOTSTRAP std::cerr << "This cmake does not support --install\n"; return -1; #else @@ -627,8 +568,18 @@ static int do_install(int ac, char const* const* av) } if (dir.empty()) { - std::cerr << "Usage: cmake --install <dir> " - "[options]\nOptions:\n" CMAKE_INSTALL_OPTIONS; + /* clang-format off */ + std::cerr << + "Usage: cmake --install <dir> [options]\n" + "Options:\n" + " <dir> = Project binary directory to install.\n" + " --config <cfg> = For multi-configuration tools, choose <cfg>.\n" + " --component <comp> = Component-based install. Only install <comp>.\n" + " --prefix <prefix> = The installation prefix CMAKE_INSTALL_PREFIX.\n" + " --strip = Performing install/strip.\n" + " -v --verbose = Enable verbose output.\n" + ; + /* clang-format on */ return 1; } @@ -671,9 +622,9 @@ static int do_install(int ac, char const* const* av) #endif } -static int do_open(int ac, char const* const* av) +int do_open(int ac, char const* const* av) { -#ifndef CMAKE_BUILD_WITH_CMAKE +#ifdef CMAKE_BOOTSTRAP std::cerr << "This cmake does not support --open\n"; return -1; #else @@ -713,3 +664,44 @@ static int do_open(int ac, char const* const* av) return cm.Open(dir, false) ? 0 : 1; #endif } +} // namespace + +int main(int ac, char const* const* av) +{ + cmSystemTools::EnsureStdPipes(); +#if defined(_WIN32) && !defined(CMAKE_BOOTSTRAP) + // Replace streambuf so we can output Unicode to console + cmsys::ConsoleBuf::Manager consoleOut(std::cout); + consoleOut.SetUTF8Pipes(); + cmsys::ConsoleBuf::Manager consoleErr(std::cerr, true); + consoleErr.SetUTF8Pipes(); +#endif + cmsys::Encoding::CommandLineArguments args = + cmsys::Encoding::CommandLineArguments::Main(ac, av); + ac = args.argc(); + av = args.argv(); + + cmSystemTools::EnableMSVCDebugHook(); + cmSystemTools::InitializeLibUV(); + cmSystemTools::FindCMakeResources(av[0]); + if (ac > 1) { + if (strcmp(av[1], "--build") == 0) { + return do_build(ac, av); + } + if (strcmp(av[1], "--install") == 0) { + return do_install(ac, av); + } + if (strcmp(av[1], "--open") == 0) { + return do_open(ac, av); + } + if (strcmp(av[1], "-E") == 0) { + return do_command(ac, av); + } + } + int ret = do_cmake(ac, av); +#ifndef CMAKE_BOOTSTRAP + cmDynamicLoader::FlushCache(); +#endif + uv_loop_close(uv_default_loop()); + return ret; +} diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx index 86082e5..2be8bae 100644 --- a/Source/cmcmd.cxx +++ b/Source/cmcmd.cxx @@ -13,23 +13,24 @@ #include "cmState.h" #include "cmStateDirectory.h" #include "cmStateSnapshot.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmUtils.hxx" #include "cmVersion.h" #include "cmake.h" -#if defined(CMAKE_BUILD_WITH_CMAKE) +#if !defined(CMAKE_BOOTSTRAP) # include "cmDependsFortran.h" // For -E cmake_copy_f90_mod callback. # include "cmServer.h" # include "cmServerConnection.h" #endif -#if defined(CMAKE_BUILD_WITH_CMAKE) && defined(_WIN32) +#if !defined(CMAKE_BOOTSTRAP) && defined(_WIN32) # include "bindexplib.h" # include "cmsys/ConsoleBuf.hxx" #endif -#if defined(CMAKE_BUILD_WITH_CMAKE) && defined(_WIN32) && !defined(__CYGWIN__) +#if !defined(CMAKE_BOOTSTRAP) && defined(_WIN32) && !defined(__CYGWIN__) # include "cmVisualStudioWCEPlatformParser.h" #endif @@ -37,11 +38,9 @@ #include "cmsys/FStream.hxx" #include "cmsys/Process.h" #include "cmsys/Terminal.h" -#include <algorithm> #include <array> #include <iostream> -#include <iterator> -#include <memory> // IWYU pragma: keep +#include <memory> #include <sstream> #include <stdio.h> #include <stdlib.h> @@ -60,7 +59,7 @@ void CMakeCommandUsage(const char* program) { std::ostringstream errorStream; -#ifdef CMAKE_BUILD_WITH_CMAKE +#ifndef CMAKE_BOOTSTRAP /* clang-format off */ errorStream << "cmake version " << cmVersion::GetCMakeVersion() << "\n"; @@ -114,6 +113,8 @@ void CMakeCommandUsage(const char* program) << " touch <file>... - touch a <file>.\n" << " touch_nocreate <file>... - touch a <file> but do not create it.\n" << " create_symlink old new - create a symbolic link new -> old\n" + << " true - do nothing with an exit code of 0\n" + << " false - do nothing with an exit code of 1\n" #if defined(_WIN32) && !defined(__CYGWIN__) << "Available on Windows only:\n" << " delete_regv key - delete registry value\n" @@ -171,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; - cmSystemTools::ExpandListArgument(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. @@ -201,8 +201,7 @@ static int HandleTidy(const std::string& runCmd, const std::string& sourceFile, // automatically skip over the compiler itself and extract the // options. int ret; - std::vector<std::string> tidy_cmd = - cmSystemTools::ExpandedListArgument(runCmd, true); + std::vector<std::string> tidy_cmd = cmExpandedList(runCmd, true); tidy_cmd.push_back(sourceFile); tidy_cmd.emplace_back("--"); cmAppend(tidy_cmd, orig_cmd); @@ -262,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; - cmSystemTools::ExpandListArgument(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. @@ -291,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; - cmSystemTools::ExpandListArgument(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) { @@ -405,7 +402,7 @@ int cmcmd::HandleCoCompileCommands(std::vector<std::string> const& args) if (cmHasLiteralPrefix(arg, "--source=")) { sourceFile = arg.substr(9); } else if (cmHasLiteralPrefix(arg, "--launcher=")) { - cmSystemTools::ExpandListArgument(arg.substr(11), launchers, true); + cmExpandList(arg.substr(11), launchers, true); } else { // if it was not a co-compiler or --source/--launcher then error std::cerr << "__run_co_compile given unknown argument: " << arg @@ -558,7 +555,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args) return 0; } -#if defined(_WIN32) && defined(CMAKE_BUILD_WITH_CMAKE) +#if defined(_WIN32) && !defined(CMAKE_BOOTSTRAP) else if (args[1] == "__create_def") { if (args.size() < 4) { std::cerr @@ -651,7 +648,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args) return 1; } -#if defined(CMAKE_BUILD_WITH_CMAKE) +#if !defined(CMAKE_BOOTSTRAP) if (args[1] == "environment") { for (auto const& env : cmSystemTools::GetEnvironmentVariables()) { std::cout << env << std::endl; @@ -763,8 +760,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(); @@ -835,8 +834,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? @@ -853,8 +851,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); @@ -891,6 +888,16 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args) return 0; } + // Command to do nothing with an exit code of 0. + if (args[1] == "true") { + return 0; + } + + // Command to do nothing with an exit code of 1. + if (args[1] == "false") { + return 1; + } + // Internal CMake shared library support. if (args[1] == "cmake_symlink_library" && args.size() == 5) { return cmcmd::SymlinkLibrary(args); @@ -933,8 +940,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args) if (args.size() >= 9 && args[8].length() >= 8 && args[8].substr(0, 8) == "--color=") { // Enable or disable color based on the switch value. - color = - (args[8].size() == 8 || cmSystemTools::IsOn(args[8].substr(8))); + color = (args[8].size() == 8 || cmIsOn(args[8].substr(8))); } } else { // Support older signature for existing makefiles: @@ -981,7 +987,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args) return cmcmd::ExecuteLinkScript(args); } -#ifdef CMAKE_BUILD_WITH_CMAKE +#ifndef CMAKE_BOOTSTRAP // Internal CMake ninja dependency scanning support. if (args[1] == "cmake_ninja_depends") { return cmcmd_cmake_ninja_depends(args.begin() + 2, args.end()); @@ -1016,7 +1022,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args) return cmcmd::ExecuteEchoColor(args); } -#ifdef CMAKE_BUILD_WITH_CMAKE +#ifndef CMAKE_BOOTSTRAP if ((args[1] == "cmake_autogen") && (args.size() >= 4)) { cmQtAutoMocUic autoGen; std::string const& infoDir = args[2]; @@ -1063,11 +1069,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; @@ -1197,7 +1199,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args) return 1; } } -#if defined(CMAKE_BUILD_WITH_CMAKE) +#if !defined(CMAKE_BOOTSTRAP) cmConnection* conn; if (isDebug) { conn = new cmServerStdIoConnection; @@ -1218,7 +1220,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args) return 1; } -#if defined(CMAKE_BUILD_WITH_CMAKE) +#if !defined(CMAKE_BOOTSTRAP) // Internal CMake Fortran module support. if (args[1] == "cmake_copy_f90_mod" && args.size() >= 4) { return cmDependsFortran::CopyModule(args) ? 0 : 1; @@ -1339,14 +1341,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) { @@ -1361,8 +1361,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) { @@ -1399,7 +1398,7 @@ int cmcmd::ExecuteEchoColor(std::vector<std::string> const& args) // Enable or disable color based on the switch value. std::string value = arg.substr(9); if (!value.empty()) { - enabled = cmSystemTools::IsOn(value); + enabled = cmIsOn(value); } } else if (cmHasLiteralPrefix(arg, "--progress-dir=")) { progressDir = arg.substr(15); @@ -1451,7 +1450,7 @@ int cmcmd::ExecuteLinkScript(std::vector<std::string> const& args) bool verbose = false; if (args.size() >= 4) { if (args[3].find("--verbose=") == 0) { - if (!cmSystemTools::IsOff(args[3].substr(10))) { + if (!cmIsOff(args[3].substr(10))) { verbose = true; } } @@ -1534,7 +1533,7 @@ int cmcmd::ExecuteLinkScript(std::vector<std::string> const& args) int cmcmd::WindowsCEEnvironment(const char* version, const std::string& name) { -#if defined(CMAKE_BUILD_WITH_CMAKE) && defined(_WIN32) && !defined(__CYGWIN__) +#if !defined(CMAKE_BOOTSTRAP) && defined(_WIN32) && !defined(__CYGWIN__) cmVisualStudioWCEPlatformParser parser(name.c_str()); parser.ParseVersion(version); if (parser.Found()) { @@ -1592,7 +1591,7 @@ private: // still works. int cmcmd::VisualStudioLink(std::vector<std::string> const& args, int type) { -#if defined(_WIN32) && defined(CMAKE_BUILD_WITH_CMAKE) +#if defined(_WIN32) && !defined(CMAKE_BOOTSTRAP) // Replace streambuf so we output in the system codepage. CMake is set up // to output in Unicode (see SetUTF8Pipes) but the Visual Studio linker // outputs using the system codepage so we need to change behavior when diff --git a/Source/ctest.cxx b/Source/ctest.cxx index 3b3630f..a69ba15 100644 --- a/Source/ctest.cxx +++ b/Source/ctest.cxx @@ -8,7 +8,7 @@ #include "cmSystemTools.h" #include "cmsys/Encoding.hxx" -#if defined(_WIN32) && defined(CMAKE_BUILD_WITH_CMAKE) +#if defined(_WIN32) && !defined(CMAKE_BOOTSTRAP) # include "cmsys/ConsoleBuf.hxx" #endif #include <iostream> @@ -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" }, @@ -144,7 +146,7 @@ static const char* cmDocumentationOptions[][2] = { int main(int argc, char const* const* argv) { cmSystemTools::EnsureStdPipes(); -#if defined(_WIN32) && defined(CMAKE_BUILD_WITH_CMAKE) +#if defined(_WIN32) && !defined(CMAKE_BOOTSTRAP) // Replace streambuf so we can output Unicode to console cmsys::ConsoleBuf::Manager consoleOut(std::cout); consoleOut.SetUTF8Pipes(); diff --git a/Source/kwsys/CommandLineArguments.cxx b/Source/kwsys/CommandLineArguments.cxx index a97f7a8..dc9f01d 100644 --- a/Source/kwsys/CommandLineArguments.cxx +++ b/Source/kwsys/CommandLineArguments.cxx @@ -67,10 +67,10 @@ class CommandLineArgumentsInternal { public: CommandLineArgumentsInternal() + : UnknownArgumentCallback{ KWSYS_NULLPTR } + , ClientData{ KWSYS_NULLPTR } + , LastArgument{ 0 } { - this->UnknownArgumentCallback = KWSYS_NULLPTR; - this->ClientData = KWSYS_NULLPTR; - this->LastArgument = 0; } typedef CommandLineArgumentsVectorOfStrings VectorOfStrings; diff --git a/Source/kwsys/RegularExpression.cxx b/Source/kwsys/RegularExpression.cxx index 5f84b19..3e10765 100644 --- a/Source/kwsys/RegularExpression.cxx +++ b/Source/kwsys/RegularExpression.cxx @@ -337,7 +337,6 @@ bool RegularExpression::compile(const char* exp) { const char* scan; const char* longest; - size_t len; int flags; if (exp == KWSYS_NULLPTR) { @@ -412,7 +411,7 @@ bool RegularExpression::compile(const char* exp) // if (flags & SPSTART) { longest = KWSYS_NULLPTR; - len = 0; + size_t len = 0; for (; scan != KWSYS_NULLPTR; scan = regnext(scan)) if (OP(scan) == EXACTLY && strlen(OPERAND(scan)) >= len) { longest = OPERAND(scan); diff --git a/Source/kwsys/RegularExpression.hxx.in b/Source/kwsys/RegularExpression.hxx.in index b7b93f9..ed86418 100644 --- a/Source/kwsys/RegularExpression.hxx.in +++ b/Source/kwsys/RegularExpression.hxx.in @@ -407,8 +407,12 @@ private: * Create an empty regular expression. */ inline RegularExpression::RegularExpression() + : regstart{} + , reganch{} + , regmust{} + , program{ 0 } + , progsize{} { - this->program = 0; } /** @@ -416,8 +420,12 @@ inline RegularExpression::RegularExpression() * compiles s. */ inline RegularExpression::RegularExpression(const char* s) + : regstart{} + , reganch{} + , regmust{} + , program{ 0 } + , progsize{} { - this->program = 0; if (s) { this->compile(s); } @@ -428,8 +436,12 @@ inline RegularExpression::RegularExpression(const char* s) * compiles s. */ inline RegularExpression::RegularExpression(const std::string& s) + : regstart{} + , reganch{} + , regmust{} + , program{ 0 } + , progsize{} { - this->program = 0; this->compile(s); } diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx index ae7a18a..36f24c7 100644 --- a/Source/kwsys/SystemTools.cxx +++ b/Source/kwsys/SystemTools.cxx @@ -3403,11 +3403,7 @@ static void SystemToolsAppendComponents( out_components.emplace_back(std::move(*i)); } } else if (!i->empty() && *i != cur) { -#if __cplusplus >= 201103L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201103L) - out_components.push_back(std::move(*i)); -#else - out_components.push_back(*i); -#endif + out_components.emplace_back(std::move(*i)); } } } @@ -4743,7 +4739,7 @@ void SystemTools::ClassInitialize() // Test progressively shorter logical-to-physical mappings. std::string cwd_str = cwd; std::string pwd_path; - Realpath(pwd_str.c_str(), pwd_path); + Realpath(pwd_str, pwd_path); while (cwd_str == pwd_path && cwd_str != pwd_str) { // The current pair of paths is a working logical mapping. cwd_changed = cwd_str; @@ -4753,7 +4749,7 @@ void SystemTools::ClassInitialize() // mapping still works. pwd_str = SystemTools::GetFilenamePath(pwd_str); cwd_str = SystemTools::GetFilenamePath(cwd_str); - Realpath(pwd_str.c_str(), pwd_path); + Realpath(pwd_str, pwd_path); } // Add the translation to keep the logical path name. |