diff options
53 files changed, 338 insertions, 226 deletions
diff --git a/.clang-tidy b/.clang-tidy index a520679..10819ef 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -13,9 +13,11 @@ modernize-*,\ -modernize-avoid-c-arrays,\ -modernize-use-nodiscard,\ -modernize-use-noexcept,\ +-modernize-use-trailing-return-type,\ -modernize-use-transparent-functors,\ performance-*,\ readability-*,\ +-readability-convert-member-functions-to-static,\ -readability-function-size,\ -readability-identifier-naming,\ -readability-implicit-bool-conversion,\ diff --git a/Help/command/list.rst b/Help/command/list.rst index 50bf417..4d339a0 100644 --- a/Help/command/list.rst +++ b/Help/command/list.rst @@ -308,6 +308,13 @@ The ``<compare>`` option should be one of: * ``STRING``: Sorts a list of strings alphabetically. This is the default behavior if the ``COMPARE`` option is not given. * ``FILE_BASENAME``: Sorts a list of pathnames of files by their basenames. +* ``NATURAL``: Sorts a list of strings using natural order + (see ``strverscmp(3)`` manual), i.e. such that contiguous digits + are compared as whole numbers. + For example: the following list `10.0 1.1 2.1 8.0 2.0 3.1` + will be sorted as `1.1 2.0 2.1 3.1 8.0 10.0` if the ``NATURAL`` + comparison is selected where it will be sorted as + `1.1 10.0 2.0 2.1 3.1 8.0` with the ``STRING`` comparison. Use the ``CASE`` keyword to select a case sensitive or case insensitive sort mode. The ``<case>`` option should be one of: diff --git a/Help/release/dev/list_natural_sort.rst b/Help/release/dev/list_natural_sort.rst new file mode 100644 index 0000000..ff74e5a --- /dev/null +++ b/Help/release/dev/list_natural_sort.rst @@ -0,0 +1,5 @@ +list_natural_sort +----------------- + +* The :command:`list` operation ``SORT`` gained the ``NATURAL`` sort + option to sort using natural order (see ``strverscmp(3)`` manual). diff --git a/Modules/CMakePrintSystemInformation.cmake b/Modules/CMakePrintSystemInformation.cmake index 8d5cf5c..d44e933 100644 --- a/Modules/CMakePrintSystemInformation.cmake +++ b/Modules/CMakePrintSystemInformation.cmake @@ -11,7 +11,7 @@ This module serves diagnostic purposes. Just include it in a project to see various internal CMake variables. #]=======================================================================] -message("CMAKE_SYSTEM is ${CMAKE_SYSTEM} ${CMAKE_SYSTEM_NAME} ${CMAKE_SYSTEM_VERSION}") +message("CMAKE_SYSTEM is ${CMAKE_SYSTEM} ${CMAKE_SYSTEM_NAME} ${CMAKE_SYSTEM_VERSION} ${CMAKE_SYSTEM_PROCESSOR}") message("CMAKE_SYSTEM file is ${CMAKE_SYSTEM_INFO_FILE}") message("CMAKE_C_COMPILER is ${CMAKE_C_COMPILER}") message("CMAKE_CXX_COMPILER is ${CMAKE_CXX_COMPILER}") diff --git a/Modules/FindCUDAToolkit.cmake b/Modules/FindCUDAToolkit.cmake index eed1d81..8d20ff9 100644 --- a/Modules/FindCUDAToolkit.cmake +++ b/Modules/FindCUDAToolkit.cmake @@ -711,8 +711,15 @@ find_path(CUDAToolkit_INCLUDE_DIR # And find the CUDA Runtime Library libcudart find_library(CUDA_CUDART NAMES cudart - PATH_SUFFIXES lib64 lib64/stubs lib/x64 + PATH_SUFFIXES lib64 lib/x64 ) +if (NOT CUDA_CUDART) + find_library(CUDA_CUDART + NAMES cudart + PATH_SUFFIXES lib64/stubs lib/x64/stubs + ) +endif() + if (NOT CUDA_CUDART AND NOT CUDAToolkit_FIND_QUIETLY) message(STATUS "Unable to find cudart library.") endif() @@ -759,9 +766,20 @@ if(CUDAToolkit_FOUND) NAMES ${search_names} HINTS ${CUDAToolkit_LIBRARY_DIR} ENV CUDA_PATH - PATH_SUFFIXES nvidia/current lib64 lib64/stubs lib/x64 lib lib/stubs + PATH_SUFFIXES nvidia/current lib64 lib/x64 lib ${arg_EXTRA_PATH_SUFFIXES} ) + # Don't try any stub directories intil we have exhausted all other + # search locations. + if(NOT CUDA_${lib_name}_LIBRARY) + find_library(CUDA_${lib_name}_LIBRARY + NAMES ${search_names} + HINTS ${CUDAToolkit_LIBRARY_DIR} + ENV CUDA_PATH + PATH_SUFFIXES lib64/stubs lib/x64/stubs lib/stubs stubs + ) + endif() + mark_as_advanced(CUDA_${lib_name}_LIBRARY) if (NOT TARGET CUDA::${lib_name} AND CUDA_${lib_name}_LIBRARY) diff --git a/Modules/FindPython/Support.cmake b/Modules/FindPython/Support.cmake index 5467b77..a990f0d 100644 --- a/Modules/FindPython/Support.cmake +++ b/Modules/FindPython/Support.cmake @@ -450,7 +450,7 @@ function (_PYTHON_GET_VERSION) set (${_PGV_PREFIX}VERSION_PATCH ${version_patch} PARENT_SCOPE) # compute ABI flags - if (version_major VERSION_GREATER 2) + if (version_major VERSION_GREATER "2") file (STRINGS "${_${_PYTHON_PREFIX}_INCLUDE_DIR}/pyconfig.h" config REGEX "(Py_DEBUG|WITH_PYMALLOC|Py_UNICODE_SIZE|MS_WIN32)") set (abi) if (config MATCHES "#[ ]*define[ ]+MS_WIN32") @@ -823,7 +823,7 @@ endif() # Set ABIs to search ## default: search any ABI -if (_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR VERSION_LESS 3) +if (_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR VERSION_LESS "3") # ABI not supported unset (_${_PYTHON_PREFIX}_FIND_ABI) set (_${_PYTHON_PREFIX}_ABIFLAGS "") @@ -1409,7 +1409,7 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) unset (${_PYTHON_PREFIX}_SITEARCH) endif() - if (_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR VERSION_GREATER_EQUAL 3) + if (_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR VERSION_GREATER_EQUAL "3") _python_get_config_var (${_PYTHON_PREFIX}_SOABI SOABI) endif() @@ -1601,7 +1601,7 @@ if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) if (_${_PYTHON_PREFIX}_COMPILER AND _${_PYTHON_PREFIX}_COMPILER_USABLE) if (${_PYTHON_PREFIX}_Interpreter_FOUND) # Compiler must be compatible with interpreter - if (${_${_PYTHON_PREFIX}_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_VERSION_MINOR} VERSION_EQUAL ${${_PYTHON_PREFIX}_VERSION_MAJOR}.${${_PYTHON_PREFIX}_VERSION_MINOR}) + if ("${_${_PYTHON_PREFIX}_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_VERSION_MINOR}" VERSION_EQUAL "${${_PYTHON_PREFIX}_VERSION_MAJOR}.${${_PYTHON_PREFIX}_VERSION_MINOR}") set (${_PYTHON_PREFIX}_Compiler_FOUND TRUE) endif() elseif (${_PYTHON_PREFIX}_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) @@ -2242,7 +2242,7 @@ if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS _python_get_version (INCLUDE PREFIX _${_PYTHON_PREFIX}_INC_) # update versioning - if (_${_PYTHON_PREFIX}_INC_VERSION VERSION_EQUAL ${_${_PYTHON_PREFIX}_VERSION}) + if (_${_PYTHON_PREFIX}_INC_VERSION VERSION_EQUAL _${_PYTHON_PREFIX}_VERSION) set (_${_PYTHON_PREFIX}_VERSION_PATCH ${_${_PYTHON_PREFIX}_INC_VERSION_PATCH}) endif() endif() @@ -2284,12 +2284,12 @@ if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS if (_${_PYTHON_PREFIX}_LIBRARY_RELEASE AND _${_PYTHON_PREFIX}_INCLUDE_DIR) if (${_PYTHON_PREFIX}_Interpreter_FOUND OR ${_PYTHON_PREFIX}_Compiler_FOUND) # development environment must be compatible with interpreter/compiler - if (${_${_PYTHON_PREFIX}_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_VERSION_MINOR} VERSION_EQUAL ${${_PYTHON_PREFIX}_VERSION_MAJOR}.${${_PYTHON_PREFIX}_VERSION_MINOR} - AND ${_${_PYTHON_PREFIX}_INC_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_INC_VERSION_MINOR} VERSION_EQUAL ${_${_PYTHON_PREFIX}_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_VERSION_MINOR}) + if ("${_${_PYTHON_PREFIX}_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_VERSION_MINOR}" VERSION_EQUAL "${${_PYTHON_PREFIX}_VERSION_MAJOR}.${${_PYTHON_PREFIX}_VERSION_MINOR}" + AND "${_${_PYTHON_PREFIX}_INC_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_INC_VERSION_MINOR}" VERSION_EQUAL "${_${_PYTHON_PREFIX}_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_VERSION_MINOR}") set (${_PYTHON_PREFIX}_Development_FOUND TRUE) endif() elseif (${_PYTHON_PREFIX}_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR - AND ${_${_PYTHON_PREFIX}_INC_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_INC_VERSION_MINOR} VERSION_EQUAL ${_${_PYTHON_PREFIX}_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_VERSION_MINOR}) + AND "${_${_PYTHON_PREFIX}_INC_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_INC_VERSION_MINOR}" VERSION_EQUAL "${_${_PYTHON_PREFIX}_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_VERSION_MINOR}") set (${_PYTHON_PREFIX}_Development_FOUND TRUE) endif() if (DEFINED _${_PYTHON_PREFIX}_FIND_ABI AND @@ -2299,7 +2299,7 @@ if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS endif() endif() - if (_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR VERSION_GREATER_EQUAL 3 + if (_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR VERSION_GREATER_EQUAL "3" AND NOT DEFINED ${_PYTHON_PREFIX}_SOABI) _python_get_config_var (${_PYTHON_PREFIX}_SOABI SOABI) endif() diff --git a/Modules/UseJava.cmake b/Modules/UseJava.cmake index 9177d16..db3fb95 100644 --- a/Modules/UseJava.cmake +++ b/Modules/UseJava.cmake @@ -377,7 +377,9 @@ function (__java_copy_file src dest comment) ARGS ${src} ${dest} DEPENDS ${src} - COMMENT ${comment}) + COMMENT ${comment} + VERBATIM + ) endfunction () function(__java_lcat VAR) @@ -615,7 +617,7 @@ function(add_jar _TARGET_NAME) OUTPUT ${CMAKE_JAVA_CLASS_OUTPUT_PATH}/java_compiled_${_TARGET_NAME} COMMAND ${CMAKE_COMMAND} -DCMAKE_JAVA_CLASS_OUTPUT_PATH=${CMAKE_JAVA_CLASS_OUTPUT_PATH} - -DCMAKE_JAR_CLASSES_PREFIX="${CMAKE_JAR_CLASSES_PREFIX}" + -DCMAKE_JAR_CLASSES_PREFIX=${CMAKE_JAR_CLASSES_PREFIX} -P ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/UseJava/ClearClassFiles.cmake COMMAND ${Java_JAVAC_EXECUTABLE} ${CMAKE_JAVA_COMPILE_FLAGS} @@ -627,15 +629,17 @@ function(add_jar _TARGET_NAME) DEPENDS ${_JAVA_COMPILE_FILES} ${_JAVA_COMPILE_FILELISTS} ${_JAVA_COMPILE_DEPENDS} ${_JAVA_SOURCES_FILE} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} COMMENT "Building Java objects for ${_TARGET_NAME}.jar" + VERBATIM ) add_custom_command( OUTPUT ${CMAKE_JAVA_CLASS_OUTPUT_PATH}/java_class_filelist COMMAND ${CMAKE_COMMAND} -DCMAKE_JAVA_CLASS_OUTPUT_PATH=${CMAKE_JAVA_CLASS_OUTPUT_PATH} - -DCMAKE_JAR_CLASSES_PREFIX="${CMAKE_JAR_CLASSES_PREFIX}" + -DCMAKE_JAR_CLASSES_PREFIX=${CMAKE_JAR_CLASSES_PREFIX} -P ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/UseJavaClassFilelist.cmake DEPENDS ${CMAKE_JAVA_CLASS_OUTPUT_PATH}/java_compiled_${_TARGET_NAME} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + VERBATIM ) else () # create an empty java_class_filelist @@ -666,6 +670,7 @@ function(add_jar _TARGET_NAME) DEPENDS ${_JAVA_RESOURCE_FILES} ${_JAVA_DEPENDS} ${CMAKE_JAVA_CLASS_OUTPUT_PATH}/java_class_filelist WORKING_DIRECTORY ${CMAKE_JAVA_CLASS_OUTPUT_PATH} COMMENT "Creating Java archive ${_JAVA_TARGET_OUTPUT_NAME}" + VERBATIM ) else () add_custom_command( @@ -681,6 +686,7 @@ function(add_jar _TARGET_NAME) WORKING_DIRECTORY ${CMAKE_JAVA_CLASS_OUTPUT_PATH} DEPENDS ${_JAVA_RESOURCE_FILES} ${_JAVA_DEPENDS} ${CMAKE_JAVA_CLASS_OUTPUT_PATH}/java_class_filelist COMMENT "Creating Java archive ${_JAVA_TARGET_OUTPUT_NAME}" + VERBATIM ) endif () diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 3fd8485..2ce3006 100644 --- a/Source/CMakeVersion.cmake +++ b/Source/CMakeVersion.cmake @@ -1,7 +1,7 @@ # CMake version number components. set(CMake_VERSION_MAJOR 3) set(CMake_VERSION_MINOR 17) -set(CMake_VERSION_PATCH 20200414) +set(CMake_VERSION_PATCH 20200415) #set(CMake_VERSION_RC 0) set(CMake_VERSION_IS_DIRTY 0) diff --git a/Source/CPack/IFW/cmCPackIFWRepository.cxx b/Source/CPack/IFW/cmCPackIFWRepository.cxx index a696549..f5e8744 100644 --- a/Source/CPack/IFW/cmCPackIFWRepository.cxx +++ b/Source/CPack/IFW/cmCPackIFWRepository.cxx @@ -21,11 +21,7 @@ bool cmCPackIFWRepository::IsValid() const switch (this->Update) { case cmCPackIFWRepository::None: - valid = !this->Url.empty(); - break; case cmCPackIFWRepository::Add: - valid = !this->Url.empty(); - break; case cmCPackIFWRepository::Remove: valid = !this->Url.empty(); break; diff --git a/Source/CTest/cmCTestBuildHandler.cxx b/Source/CTest/cmCTestBuildHandler.cxx index 90c5b2a..35c2b11 100644 --- a/Source/CTest/cmCTestBuildHandler.cxx +++ b/Source/CTest/cmCTestBuildHandler.cxx @@ -541,11 +541,11 @@ void cmCTestBuildHandler::GenerateXMLLaunched(cmXMLWriter& xml) const char* fname = launchDir.GetFile(i); if (this->IsLaunchedErrorFile(fname) && numErrorsAllowed) { numErrorsAllowed--; - fragments.insert(this->CTestLaunchDir + "/" + fname); + fragments.insert(this->CTestLaunchDir + '/' + fname); ++this->TotalErrors; } else if (this->IsLaunchedWarningFile(fname) && numWarningsAllowed) { numWarningsAllowed--; - fragments.insert(this->CTestLaunchDir + "/" + fname); + fragments.insert(this->CTestLaunchDir + '/' + fname); ++this->TotalWarnings; } } diff --git a/Source/CTest/cmCTestCVS.cxx b/Source/CTest/cmCTestCVS.cxx index 45ec390..1209e06 100644 --- a/Source/CTest/cmCTestCVS.cxx +++ b/Source/CTest/cmCTestCVS.cxx @@ -152,10 +152,12 @@ private: this->FinishRevision(); } } else if (this->Section == SectionRevisions) { + // XXX(clang-tidy): https://bugs.llvm.org/show_bug.cgi?id=44165 + // NOLINTNEXTLINE(bugprone-branch-clone) if (!this->Rev.Log.empty()) { // Continue the existing log. this->Rev.Log += this->Line; - this->Rev.Log += "\n"; + this->Rev.Log += '\n'; } else if (this->Rev.Rev.empty() && this->RegexRevision.find(this->Line)) { this->Rev.Rev = this->RegexRevision.match(1); @@ -166,7 +168,7 @@ private: } else if (!this->RegexBranches.find(this->Line)) { // Start the log. this->Rev.Log += this->Line; - this->Rev.Log += "\n"; + this->Rev.Log += '\n'; } } return this->Section != SectionEnd; diff --git a/Source/CTest/cmCTestMemCheckHandler.cxx b/Source/CTest/cmCTestMemCheckHandler.cxx index c1ecaf1..7ad87f5 100644 --- a/Source/CTest/cmCTestMemCheckHandler.cxx +++ b/Source/CTest/cmCTestMemCheckHandler.cxx @@ -957,35 +957,25 @@ bool cmCTestMemCheckHandler::ProcessMemCheckValgrindOutput( "valgrind line " << lines[cc] << std::endl, this->Quiet); int failure = cmCTestMemCheckHandler::NO_MEMORY_FAULT; - if (vgFIM.find(lines[cc])) { + auto& line = lines[cc]; + if (vgFIM.find(line)) { failure = cmCTestMemCheckHandler::FIM; - } else if (vgFMM.find(lines[cc])) { + } else if (vgFMM.find(line)) { failure = cmCTestMemCheckHandler::FMM; - } else if (vgMLK1.find(lines[cc])) { + } else if (vgMLK1.find(line) || vgMLK2.find(line)) { failure = cmCTestMemCheckHandler::MLK; - } else if (vgMLK2.find(lines[cc])) { - failure = cmCTestMemCheckHandler::MLK; - } else if (vgPAR.find(lines[cc])) { + } else if (vgPAR.find(line)) { failure = cmCTestMemCheckHandler::PAR; - } else if (vgMPK1.find(lines[cc])) { - failure = cmCTestMemCheckHandler::MPK; - } else if (vgMPK2.find(lines[cc])) { + } else if (vgMPK1.find(line) || vgMPK2.find(line)) { failure = cmCTestMemCheckHandler::MPK; - } else if (vgUMC.find(lines[cc])) { + } else if (vgUMC.find(line)) { failure = cmCTestMemCheckHandler::UMC; - } else if (vgUMR1.find(lines[cc])) { - failure = cmCTestMemCheckHandler::UMR; - } else if (vgUMR2.find(lines[cc])) { - failure = cmCTestMemCheckHandler::UMR; - } else if (vgUMR3.find(lines[cc])) { + } else if (vgUMR1.find(line) || vgUMR2.find(line) || vgUMR3.find(line) || + vgUMR4.find(line) || vgUMR5.find(line)) { failure = cmCTestMemCheckHandler::UMR; - } else if (vgUMR4.find(lines[cc])) { - failure = cmCTestMemCheckHandler::UMR; - } else if (vgUMR5.find(lines[cc])) { - failure = cmCTestMemCheckHandler::UMR; - } else if (vgIPW.find(lines[cc])) { + } else if (vgIPW.find(line)) { failure = cmCTestMemCheckHandler::IPW; - } else if (vgABR.find(lines[cc])) { + } else if (vgABR.find(line)) { failure = cmCTestMemCheckHandler::ABR; } @@ -1049,13 +1039,9 @@ bool cmCTestMemCheckHandler::ProcessMemCheckDrMemoryOutput( ostr << l << std::endl; if (drMemoryError.find(l)) { defects++; - if (unaddressableAccess.find(l)) { + if (unaddressableAccess.find(l) || uninitializedRead.find(l)) { results[cmCTestMemCheckHandler::UMR]++; - } else if (uninitializedRead.find(l)) { - results[cmCTestMemCheckHandler::UMR]++; - } else if (leak.find(l)) { - results[cmCTestMemCheckHandler::MLK]++; - } else if (handleLeak.find(l)) { + } else if (leak.find(l) || handleLeak.find(l)) { results[cmCTestMemCheckHandler::MLK]++; } else if (invalidHeapArgument.find(l)) { results[cmCTestMemCheckHandler::FMM]++; diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx index f9850ef..ca65946 100644 --- a/Source/CTest/cmCTestTestHandler.cxx +++ b/Source/CTest/cmCTestTestHandler.cxx @@ -2402,10 +2402,9 @@ bool cmCTestTestHandler::AddTest(const std::vector<std::string>& args) test.SkipReturnCode = -1; test.PreviousRuns = 0; if (this->UseIncludeRegExpFlag && - !this->IncludeTestsRegularExpression.find(testname)) { - test.IsInBasedOnREOptions = false; - } else if (this->UseExcludeRegExpFlag && !this->UseExcludeRegExpFirst && - this->ExcludeTestsRegularExpression.find(testname)) { + (!this->IncludeTestsRegularExpression.find(testname) || + (!this->UseExcludeRegExpFirst && + this->ExcludeTestsRegularExpression.find(testname)))) { test.IsInBasedOnREOptions = false; } this->TestList.push_back(test); diff --git a/Source/CTest/cmParseCacheCoverage.cxx b/Source/CTest/cmParseCacheCoverage.cxx index 1a5e7c5..84d7de0 100644 --- a/Source/CTest/cmParseCacheCoverage.cxx +++ b/Source/CTest/cmParseCacheCoverage.cxx @@ -4,6 +4,7 @@ #include <cstdlib> #include <map> #include <utility> +#include <vector> #include "cmsys/Directory.hxx" #include "cmsys/FStream.hxx" @@ -69,26 +70,6 @@ void cmParseCacheCoverage::RemoveUnCoveredFiles() } } -bool cmParseCacheCoverage::SplitString(std::vector<std::string>& args, - std::string const& line) -{ - std::string::size_type pos1 = 0; - std::string::size_type pos2 = line.find(',', 0); - if (pos2 == std::string::npos) { - return false; - } - std::string arg; - while (pos2 != std::string::npos) { - arg = line.substr(pos1, pos2 - pos1); - args.push_back(arg); - pos1 = pos2 + 1; - pos2 = line.find(',', pos1); - } - arg = line.substr(pos1); - args.push_back(arg); - return true; -} - bool cmParseCacheCoverage::ReadCMCovFile(const char* file) { cmsys::ifstream in(file); @@ -97,7 +78,6 @@ bool cmParseCacheCoverage::ReadCMCovFile(const char* file) return false; } std::string line; - std::vector<std::string> separateLine; if (!cmSystemTools::GetLineFromStream(in, line)) { cmCTestLog(this->CTest, ERROR_MESSAGE, "Empty file : " << file @@ -106,8 +86,8 @@ bool cmParseCacheCoverage::ReadCMCovFile(const char* file) << line << "]\n"); return false; } - separateLine.clear(); - this->SplitString(separateLine, line); + std::vector<std::string> separateLine = + cmSystemTools::SplitString(line, ','); if (separateLine.size() != 4 || separateLine[0] != "Routine" || separateLine[1] != "Line" || separateLine[2] != "RtnLine" || separateLine[3] != "Code") { @@ -120,10 +100,8 @@ bool cmParseCacheCoverage::ReadCMCovFile(const char* file) std::string routine; std::string filepath; while (cmSystemTools::GetLineFromStream(in, line)) { - // clear out line argument vector - separateLine.clear(); // parse the comma separated line - this->SplitString(separateLine, line); + separateLine = cmSystemTools::SplitString(line, ','); // might have more because code could have a quoted , in it // but we only care about the first 3 args anyway if (separateLine.size() < 4) { diff --git a/Source/CTest/cmParseCacheCoverage.h b/Source/CTest/cmParseCacheCoverage.h index 3b554f3..a8200b7 100644 --- a/Source/CTest/cmParseCacheCoverage.h +++ b/Source/CTest/cmParseCacheCoverage.h @@ -6,7 +6,6 @@ #include "cmConfigure.h" // IWYU pragma: keep #include <string> -#include <vector> #include "cmParseMumpsCoverage.h" @@ -31,8 +30,6 @@ protected: void RemoveUnCoveredFiles(); // Read a single mcov file bool ReadCMCovFile(const char* f); - // split a string based on , - bool SplitString(std::vector<std::string>& args, std::string const& line); }; #endif diff --git a/Source/QtDialog/CMakeSetupDialog.cxx b/Source/QtDialog/CMakeSetupDialog.cxx index 276bf64..4daf726 100644 --- a/Source/QtDialog/CMakeSetupDialog.cxx +++ b/Source/QtDialog/CMakeSetupDialog.cxx @@ -804,6 +804,9 @@ bool CMakeSetupDialog::setupFirstConfigure() QString systemVersion = dialog.getSystemVersion(); m->insertProperty(QCMakeProperty::STRING, "CMAKE_SYSTEM_VERSION", tr("CMake System Version"), systemVersion, false); + QString systemProcessor = dialog.getSystemProcessor(); + m->insertProperty(QCMakeProperty::STRING, "CMAKE_SYSTEM_PROCESSOR", + tr("CMake System Processor"), systemProcessor, false); QString cxxCompiler = dialog.getCXXCompiler(); m->insertProperty(QCMakeProperty::FILEPATH, "CMAKE_CXX_COMPILER", tr("CXX compiler."), cxxCompiler, false); diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx index c5505f9..35a8952 100644 --- a/Source/cmCTest.cxx +++ b/Source/cmCTest.cxx @@ -1941,13 +1941,11 @@ bool cmCTest::HandleCommandLineArguments(size_t& i, else if (this->CheckArgument(arg, "--debug"_s)) { this->Impl->Debug = true; this->Impl->ShowLineNumbers = true; - } else if (this->CheckArgument(arg, "--group"_s) && i < args.size() - 1) { - i++; - this->Impl->SpecificGroup = args[i]; - } - // This is an undocumented / deprecated option. - // "Track" has been renamed to "Group". - else if (this->CheckArgument(arg, "--track"_s) && i < args.size() - 1) { + } else if ((this->CheckArgument(arg, "--group"_s) || + // This is an undocumented / deprecated option. + // "Track" has been renamed to "Group". + this->CheckArgument(arg, "--track"_s)) && + i < args.size() - 1) { i++; this->Impl->SpecificGroup = args[i]; } else if (this->CheckArgument(arg, "--show-line-numbers"_s)) { diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx index 8d27699..d8a6204 100644 --- a/Source/cmComputeLinkInformation.cxx +++ b/Source/cmComputeLinkInformation.cxx @@ -998,15 +998,16 @@ std::string cmComputeLinkInformation::CreateExtensionRegex( std::string cmComputeLinkInformation::NoCaseExpression(const char* str) { std::string ret; + ret.reserve(strlen(str) * 4); const char* s = str; while (*s) { if (*s == '.') { ret += *s; } else { - ret += "["; + ret += '['; ret += static_cast<char>(tolower(*s)); ret += static_cast<char>(toupper(*s)); - ret += "]"; + ret += ']'; } s++; } @@ -1440,7 +1441,6 @@ void cmComputeLinkInformation::HandleBadFullItem(std::string const& item, } case cmPolicies::OLD: // OLD behavior does not warn. - break; case cmPolicies::NEW: // NEW behavior will not get here. break; diff --git a/Source/cmConfigureFileCommand.cxx b/Source/cmConfigureFileCommand.cxx index 8767386..bac9337 100644 --- a/Source/cmConfigureFileCommand.cxx +++ b/Source/cmConfigureFileCommand.cxx @@ -2,6 +2,12 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmConfigureFileCommand.h" +#include <set> + +#include <cm/string_view> + +#include "cm_static_string_view.hxx" + #include "cmExecutionStatus.h" #include "cmMakefile.h" #include "cmMessageType.h" @@ -56,6 +62,18 @@ bool cmConfigureFileCommand(std::vector<std::string> const& args, bool copyOnly = false; bool escapeQuotes = false; + static std::set<cm::string_view> noopOptions = { + /* Legacy. */ + "IMMEDIATE"_s, + /* Handled by NewLineStyle member. */ + "NEWLINE_STYLE"_s, + "LF"_s, + "UNIX"_s, + "CRLF"_s, + "WIN32"_s, + "DOS"_s, + }; + std::string unknown_args; bool atOnly = false; for (unsigned int i = 2; i < args.size(); ++i) { @@ -70,12 +88,8 @@ bool cmConfigureFileCommand(std::vector<std::string> const& args, escapeQuotes = true; } else if (args[i] == "@ONLY") { atOnly = true; - } else if (args[i] == "IMMEDIATE") { - /* Ignore legacy option. */ - } else if (args[i] == "NEWLINE_STYLE" || args[i] == "LF" || - args[i] == "UNIX" || args[i] == "CRLF" || args[i] == "WIN32" || - args[i] == "DOS") { - /* Options handled by NewLineStyle member above. */ + } else if (noopOptions.find(args[i]) != noopOptions.end()) { + /* Ignore no-op options. */ } else { unknown_args += " "; unknown_args += args[i]; diff --git a/Source/cmCustomCommand.cxx b/Source/cmCustomCommand.cxx index 0dd8722..149f5e9 100644 --- a/Source/cmCustomCommand.cxx +++ b/Source/cmCustomCommand.cxx @@ -11,7 +11,8 @@ cmCustomCommand::cmCustomCommand(std::vector<std::string> outputs, std::vector<std::string> depends, cmCustomCommandLines commandLines, cmListFileBacktrace lfbt, const char* comment, - const char* workingDirectory) + const char* workingDirectory, + bool stdPipesUTF8) : Outputs(std::move(outputs)) , Byproducts(std::move(byproducts)) , Depends(std::move(depends)) @@ -20,6 +21,7 @@ cmCustomCommand::cmCustomCommand(std::vector<std::string> outputs, , Comment(comment ? comment : "") , WorkingDirectory(workingDirectory ? workingDirectory : "") , HaveComment(comment != nullptr) + , StdPipesUTF8(stdPipesUTF8) { } diff --git a/Source/cmCustomCommand.h b/Source/cmCustomCommand.h index d300fa5..aa572ad 100644 --- a/Source/cmCustomCommand.h +++ b/Source/cmCustomCommand.h @@ -30,7 +30,8 @@ public: std::vector<std::string> byproducts, std::vector<std::string> depends, cmCustomCommandLines commandLines, cmListFileBacktrace lfbt, - const char* comment, const char* workingDirectory); + const char* comment, const char* workingDirectory, + bool stdPipesUTF8); /** Get the output file produced by the command. */ const std::vector<std::string>& GetOutputs() const; @@ -53,6 +54,9 @@ public: /** Get the comment string for the command. */ const char* GetComment() const; + /** Get a value indicating if the command uses UTF-8 output pipes. */ + bool GetStdPipesUTF8() const { return this->StdPipesUTF8; } + /** Append to the list of command lines. */ void AppendCommands(const cmCustomCommandLines& commandLines); @@ -108,6 +112,7 @@ private: bool EscapeOldStyle = true; bool UsesTerminal = false; bool CommandExpandLists = false; + bool StdPipesUTF8 = false; }; #endif diff --git a/Source/cmDependsFortran.cxx b/Source/cmDependsFortran.cxx index 666306c..c45cd1c 100644 --- a/Source/cmDependsFortran.cxx +++ b/Source/cmDependsFortran.cxx @@ -29,12 +29,10 @@ static void cmFortranModuleAppendUpperLower(std::string const& mod, std::string& mod_lower) { std::string::size_type ext_len = 0; - if (cmHasLiteralSuffix(mod, ".mod")) { + if (cmHasLiteralSuffix(mod, ".mod") || cmHasLiteralSuffix(mod, ".sub")) { ext_len = 4; } else if (cmHasLiteralSuffix(mod, ".smod")) { ext_len = 5; - } else if (cmHasLiteralSuffix(mod, ".sub")) { - ext_len = 4; } std::string const& name = mod.substr(0, mod.size() - ext_len); std::string const& ext = mod.substr(mod.size() - ext_len); diff --git a/Source/cmExtraCodeLiteGenerator.cxx b/Source/cmExtraCodeLiteGenerator.cxx index de40c77..bf7555d 100644 --- a/Source/cmExtraCodeLiteGenerator.cxx +++ b/Source/cmExtraCodeLiteGenerator.cxx @@ -204,9 +204,7 @@ std::string cmExtraCodeLiteGenerator::CollectSourceFiles( case cmStateEnums::STATIC_LIBRARY: { projectType = "Static Library"; } break; - case cmStateEnums::SHARED_LIBRARY: { - projectType = "Dynamic Library"; - } break; + case cmStateEnums::SHARED_LIBRARY: case cmStateEnums::MODULE_LIBRARY: { projectType = "Dynamic Library"; } break; diff --git a/Source/cmExtraEclipseCDT4Generator.cxx b/Source/cmExtraEclipseCDT4Generator.cxx index 1c5bcaa..b65f097 100644 --- a/Source/cmExtraEclipseCDT4Generator.cxx +++ b/Source/cmExtraEclipseCDT4Generator.cxx @@ -981,7 +981,6 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const } } break; case cmStateEnums::INTERFACE_LIBRARY: - break; default: break; } diff --git a/Source/cmExtraKateGenerator.cxx b/Source/cmExtraKateGenerator.cxx index 271bbee..01fac5a 100644 --- a/Source/cmExtraKateGenerator.cxx +++ b/Source/cmExtraKateGenerator.cxx @@ -129,9 +129,8 @@ void cmExtraKateGenerator::WriteTargets(const cmLocalGenerator& lg, if (targetName == "edit_cache") { const char* editCommand = localGen->GetMakefile()->GetDefinition("CMAKE_EDIT_COMMAND"); - if (editCommand == nullptr) { - insertTarget = false; - } else if (strstr(editCommand, "ccmake") != nullptr) { + if (editCommand == nullptr || + strstr(editCommand, "ccmake") != nullptr) { insertTarget = false; } } @@ -274,7 +273,7 @@ std::string cmExtraKateGenerator::GenerateProjectName( const std::string& name, const std::string& type, const std::string& path) const { - return name + (type.empty() ? "" : "-") + type + "@" + path; + return name + (type.empty() ? "" : "-") + type + '@' + path; } std::string cmExtraKateGenerator::GetPathBasename( diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx index e996327..d1517fe 100644 --- a/Source/cmFindPackageCommand.cxx +++ b/Source/cmFindPackageCommand.cxx @@ -279,9 +279,13 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args) } else if (args[i] == "MODULE") { moduleArgs.insert(i); doing = DoingNone; + // XXX(clang-tidy): https://bugs.llvm.org/show_bug.cgi?id=44165 + // NOLINTNEXTLINE(bugprone-branch-clone) } else if (args[i] == "CONFIG") { configArgs.insert(i); doing = DoingNone; + // XXX(clang-tidy): https://bugs.llvm.org/show_bug.cgi?id=44165 + // NOLINTNEXTLINE(bugprone-branch-clone) } else if (args[i] == "NO_MODULE") { configArgs.insert(i); doing = DoingNone; @@ -318,6 +322,8 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args) this->NoSystemRegistry = true; configArgs.insert(i); doing = DoingNone; + // XXX(clang-tidy): https://bugs.llvm.org/show_bug.cgi?id=44165 + // NOLINTNEXTLINE(bugprone-branch-clone) } else if (args[i] == "NO_CMAKE_BUILDS_PATH") { // Ignore legacy option. configArgs.insert(i); diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index 611f7b0..93eb8fb 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -1227,7 +1227,6 @@ std::string cmGeneratorTarget::EvaluateInterfaceProperty( 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; @@ -1295,10 +1294,9 @@ std::string AddSwiftInterfaceIncludeDirectories( dag.ReportError(nullptr, "$<TARGET_PROPERTY:" + target->GetName() + ",Swift_MODULE_DIRECTORY>"); - return ""; + CM_FALLTHROUGH; case cmGeneratorExpressionDAGChecker::CYCLIC_REFERENCE: // No error. We just skip cyclic references. - return ""; case cmGeneratorExpressionDAGChecker::ALREADY_SEEN: // No error. We have already seen this transitive property. return ""; @@ -1689,10 +1687,14 @@ void cmGeneratorTarget::ComputeKindedSources(KindedSources& files, std::string ext = cmSystemTools::LowerCase(sf->GetExtension()); if (sf->GetCustomCommand()) { kind = SourceKindCustomCommand; + // XXX(clang-tidy): https://bugs.llvm.org/show_bug.cgi?id=44165 + // NOLINTNEXTLINE(bugprone-branch-clone) } else if (this->Target->GetType() == cmStateEnums::UTILITY) { kind = SourceKindExtra; } else if (this->IsSourceFilePartOfUnityBatch(sf->ResolveFullPath())) { kind = SourceKindUnityBatched; + // XXX(clang-tidy): https://bugs.llvm.org/show_bug.cgi?id=44165 + // NOLINTNEXTLINE(bugprone-branch-clone) } else if (sf->GetPropertyAsBool("HEADER_FILE_ONLY")) { kind = SourceKindHeader; } else if (sf->GetPropertyAsBool("EXTERNAL_OBJECT")) { diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index ccbbf53..035c608 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -2253,10 +2253,12 @@ std::string cmGlobalGenerator::IndexGeneratorTargetUniquely( // Use a ":" prefix to avoid conflict with project-defined targets. // We must satisfy cmGeneratorExpression::IsValidTargetName so use no // other special characters. - char buf[1 + sizeof(gt) * 2]; + constexpr size_t sizeof_ptr = + sizeof(gt); // NOLINT(bugprone-sizeof-expression) + char buf[1 + sizeof_ptr * 2]; char* b = buf; *b++ = ':'; - for (size_t i = 0; i < sizeof(gt); ++i) { + for (size_t i = 0; i < sizeof_ptr; ++i) { unsigned char const c = reinterpret_cast<unsigned char const*>(>)[i]; *b++ = hexDigits[(c & 0xf0) >> 4]; *b++ = hexDigits[(c & 0x0f)]; @@ -2543,6 +2545,7 @@ void cmGlobalGenerator::AddGlobalTarget_EditCache( singleLine.push_back("No interactive CMake dialog available."); gti.Message = "No interactive CMake dialog available..."; gti.UsesTerminal = false; + gti.StdPipesUTF8 = true; } gti.CommandLines.push_back(std::move(singleLine)); @@ -2567,6 +2570,7 @@ void cmGlobalGenerator::AddGlobalTarget_RebuildCache( singleLine.push_back("-S$(CMAKE_SOURCE_DIR)"); singleLine.push_back("-B$(CMAKE_BINARY_DIR)"); gti.CommandLines.push_back(std::move(singleLine)); + gti.StdPipesUTF8 = true; targets.push_back(std::move(gti)); } @@ -2603,6 +2607,7 @@ void cmGlobalGenerator::AddGlobalTarget_Install( gti.Name = this->GetInstallTargetName(); gti.Message = "Install the project..."; gti.UsesTerminal = true; + gti.StdPipesUTF8 = true; cmCustomCommandLine singleLine; if (this->GetPreinstallTargetName()) { gti.Depends.emplace_back(this->GetPreinstallTargetName()); @@ -2714,7 +2719,8 @@ cmTarget cmGlobalGenerator::CreateGlobalTarget(GlobalTargetInfo const& gti, std::vector<std::string> no_depends; // Store the custom command in the target. cmCustomCommand cc(no_outputs, no_byproducts, no_depends, gti.CommandLines, - cmListFileBacktrace(), nullptr, gti.WorkingDir.c_str()); + cmListFileBacktrace(), nullptr, gti.WorkingDir.c_str(), + gti.StdPipesUTF8); cc.SetUsesTerminal(gti.UsesTerminal); target.AddPostBuildCommand(std::move(cc)); if (!gti.Message.empty()) { diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index 70e43b5..a76ab3c 100644 --- a/Source/cmGlobalGenerator.h +++ b/Source/cmGlobalGenerator.h @@ -554,6 +554,7 @@ protected: std::string WorkingDir; bool UsesTerminal = false; bool PerConfig = true; + bool StdPipesUTF8 = false; }; void CreateDefaultGlobalTargets(std::vector<GlobalTargetInfo>& targets); diff --git a/Source/cmGlobalVisualStudio8Generator.cxx b/Source/cmGlobalVisualStudio8Generator.cxx index fa0e935..1df76ca 100644 --- a/Source/cmGlobalVisualStudio8Generator.cxx +++ b/Source/cmGlobalVisualStudio8Generator.cxx @@ -142,6 +142,9 @@ bool cmGlobalVisualStudio8Generator::AddCheckTarget() // Add a custom rule to re-run CMake if any input files changed. { + // The custom rule runs cmake so set UTF-8 pipes. + bool stdPipesUTF8 = true; + // Collect the input files used to generate all targets in this // project. std::vector<std::string> listFiles; @@ -160,7 +163,7 @@ bool cmGlobalVisualStudio8Generator::AddCheckTarget() lg.AddCustomCommandToTarget( CMAKE_CHECK_BUILD_SYSTEM_TARGET, byproducts, no_depends, verifyCommandLines, cmCustomCommandType::PRE_BUILD, - "Checking File Globs", no_working_directory, false); + "Checking File Globs", no_working_directory, stdPipesUTF8); // Ensure ZERO_CHECK always runs in Visual Studio using MSBuild, // otherwise the prebuild command will not be run. @@ -192,7 +195,8 @@ bool cmGlobalVisualStudio8Generator::AddCheckTarget() if (cmSourceFile* file = lg.AddCustomCommandToOutput( stamps, no_byproducts, listFiles, no_main_dependency, no_implicit_depends, commandLines, "Checking Build System", - no_working_directory, true, false)) { + no_working_directory, true, false, false, false, "", "", + stdPipesUTF8)) { gt->AddSource(file->ResolveFullPath()); } else { cmSystemTools::Error("Error adding rule for " + stamps[0]); diff --git a/Source/cmGlobalVisualStudioGenerator.cxx b/Source/cmGlobalVisualStudioGenerator.cxx index d2f9760..b9f4609 100644 --- a/Source/cmGlobalVisualStudioGenerator.cxx +++ b/Source/cmGlobalVisualStudioGenerator.cxx @@ -932,7 +932,7 @@ void cmGlobalVisualStudioGenerator::AddSymbolExportCommand( { cmakeCommand, "-E", "__create_def", mdi->DefFile, objs_file }); cmCustomCommand command(outputs, empty, empty, commandLines, gt->Target->GetMakefile()->GetBacktrace(), - "Auto build dll exports", "."); + "Auto build dll exports", ".", true); commands.push_back(std::move(command)); } diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index bdc03c7..c7d7133 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -1464,6 +1464,7 @@ void cmGlobalXCodeGenerator::CreateCustomCommands( cmStrCat("$<TARGET_SONAME_FILE:", gtgt->GetName(), '>'); std::string str_link_file = cmStrCat("$<TARGET_LINKER_FILE:", gtgt->GetName(), '>'); + bool stdPipesUTF8 = true; cmCustomCommandLines cmd = cmMakeSingleCommandLine( { cmSystemTools::GetCMakeCommand(), "-E", "cmake_symlink_library", str_file, str_so_file, str_link_file }); @@ -1471,7 +1472,7 @@ void cmGlobalXCodeGenerator::CreateCustomCommands( cmCustomCommand command( std::vector<std::string>(), std::vector<std::string>(), std::vector<std::string>(), cmd, this->CurrentMakefile->GetBacktrace(), - "Creating symlinks", ""); + "Creating symlinks", "", stdPipesUTF8); postbuild.push_back(std::move(command)); } diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx index 704db66..c9b22b6 100644 --- a/Source/cmInstallCommand.cxx +++ b/Source/cmInstallCommand.cxx @@ -661,7 +661,6 @@ bool HandleTargetsMode(std::vector<std::string> const& args, // Nothing to do. An INTERFACE_LIBRARY can be installed, but the // only effect of that is to make it exportable. It installs no // other files itself. - break; default: // This should never happen due to the above type check. // Ignore the case. diff --git a/Source/cmListCommand.cxx b/Source/cmListCommand.cxx index 5200a16..860b4da 100644 --- a/Source/cmListCommand.cxx +++ b/Source/cmListCommand.cxx @@ -1051,6 +1051,7 @@ public: UNINITIALIZED, STRING, FILE_BASENAME, + NATURAL, }; enum class CaseSensitivity { @@ -1074,10 +1075,25 @@ protected: : nullptr; } + using ComparisonFunction = + std::function<bool(const std::string&, const std::string&)>; + ComparisonFunction GetComparisonFunction(Compare compare) + { + if (compare == Compare::NATURAL) { + return std::function<bool(const std::string&, const std::string&)>( + [](const std::string& x, const std::string& y) { + return cmSystemTools::strverscmp(x, y) < 0; + }); + } + return std::function<bool(const std::string&, const std::string&)>( + [](const std::string& x, const std::string& y) { return x < y; }); + } + public: cmStringSorter(Compare compare, CaseSensitivity caseSensitivity, Order desc = Order::ASCENDING) : filters{ GetCompareFilter(compare), GetCaseFilter(caseSensitivity) } + , sortMethod(GetComparisonFunction(compare)) , descending(desc == Order::DESCENDING) { } @@ -1099,15 +1115,16 @@ public: std::string bf = ApplyFilter(b); bool result; if (descending) { - result = bf < af; + result = sortMethod(bf, af); } else { - result = af < bf; + result = sortMethod(af, bf); } return result; } protected: StringFilter filters[2] = { nullptr, nullptr }; + ComparisonFunction sortMethod; bool descending; }; @@ -1142,6 +1159,8 @@ bool HandleSortCommand(std::vector<std::string> const& args, sortCompare = cmStringSorter::Compare::STRING; } else if (argument == "FILE_BASENAME") { sortCompare = cmStringSorter::Compare::FILE_BASENAME; + } else if (argument == "NATURAL") { + sortCompare = cmStringSorter::Compare::NATURAL; } else { std::string error = cmStrCat(messageHint, "value \"", argument, "\" for option \"", diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index f5ca5f4..43de0fc 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -1089,7 +1089,8 @@ cmTarget* cmLocalGenerator::AddCustomCommandToTarget( const cmCustomCommandLines& commandLines, cmCustomCommandType type, const char* comment, const char* workingDir, bool escapeOldStyle, bool uses_terminal, const std::string& depfile, const std::string& job_pool, - bool command_expand_lists, cmObjectLibraryCommands objLibCommands) + bool command_expand_lists, cmObjectLibraryCommands objLibCommands, + bool stdPipesUTF8) { cmTarget* t = this->Makefile->GetCustomCommandTarget( target, objLibCommands, this->DirectoryBacktrace); @@ -1100,7 +1101,7 @@ cmTarget* cmLocalGenerator::AddCustomCommandToTarget( detail::AddCustomCommandToTarget( *this, this->DirectoryBacktrace, cmCommandOrigin::Generator, t, byproducts, depends, commandLines, type, comment, workingDir, escapeOldStyle, - uses_terminal, depfile, job_pool, command_expand_lists); + uses_terminal, depfile, job_pool, command_expand_lists, stdPipesUTF8); return t; } @@ -1110,14 +1111,14 @@ cmSourceFile* cmLocalGenerator::AddCustomCommandToOutput( const std::string& main_dependency, const cmCustomCommandLines& commandLines, const char* comment, const char* workingDir, bool replace, bool escapeOldStyle, bool uses_terminal, bool command_expand_lists, - const std::string& depfile, const std::string& job_pool) + const std::string& depfile, const std::string& job_pool, bool stdPipesUTF8) { std::vector<std::string> no_byproducts; cmImplicitDependsList no_implicit_depends; return this->AddCustomCommandToOutput( { output }, no_byproducts, depends, main_dependency, no_implicit_depends, commandLines, comment, workingDir, replace, escapeOldStyle, uses_terminal, - command_expand_lists, depfile, job_pool); + command_expand_lists, depfile, job_pool, stdPipesUTF8); } cmSourceFile* cmLocalGenerator::AddCustomCommandToOutput( @@ -1128,7 +1129,7 @@ cmSourceFile* cmLocalGenerator::AddCustomCommandToOutput( const cmCustomCommandLines& commandLines, const char* comment, const char* workingDir, bool replace, bool escapeOldStyle, bool uses_terminal, bool command_expand_lists, const std::string& depfile, - const std::string& job_pool) + const std::string& job_pool, bool stdPipesUTF8) { // Make sure there is at least one output. if (outputs.empty()) { @@ -1140,7 +1141,7 @@ cmSourceFile* cmLocalGenerator::AddCustomCommandToOutput( *this, this->DirectoryBacktrace, cmCommandOrigin::Generator, outputs, byproducts, depends, main_dependency, implicit_depends, commandLines, comment, workingDir, replace, escapeOldStyle, uses_terminal, - command_expand_lists, depfile, job_pool); + command_expand_lists, depfile, job_pool, stdPipesUTF8); } cmTarget* cmLocalGenerator::AddUtilityCommand( @@ -1149,7 +1150,7 @@ cmTarget* cmLocalGenerator::AddUtilityCommand( const std::vector<std::string>& depends, const cmCustomCommandLines& commandLines, bool escapeOldStyle, const char* comment, bool uses_terminal, bool command_expand_lists, - const std::string& job_pool) + const std::string& job_pool, bool stdPipesUTF8) { cmTarget* target = this->Makefile->AddNewUtilityTarget(utilityName, excludeFromAll); @@ -1163,7 +1164,7 @@ cmTarget* cmLocalGenerator::AddUtilityCommand( *this, this->DirectoryBacktrace, cmCommandOrigin::Generator, target, this->Makefile->GetUtilityOutput(target), workingDir, byproducts, depends, commandLines, escapeOldStyle, comment, uses_terminal, command_expand_lists, - job_pool); + job_pool, stdPipesUTF8); return target; } @@ -2070,11 +2071,9 @@ bool cmLocalGenerator::GetRealDependency(const std::string& inName, case cmStateEnums::OBJECT_LIBRARY: // An object library has no single file on which to depend. // This was listed to get the target-level dependency. - return false; case cmStateEnums::INTERFACE_LIBRARY: // An interface library has no file on which to depend. // This was listed to get the target-level dependency. - return false; case cmStateEnums::UTILITY: case cmStateEnums::GLOBAL_TARGET: // A utility target has no file on which to depend. This was listed @@ -2650,6 +2649,7 @@ void cmLocalGenerator::AddPchDependencies(cmGeneratorTarget* target) file << "endif()\n"; } + bool stdPipesUTF8 = true; cmCustomCommandLines commandLines = cmMakeSingleCommandLine( { cmSystemTools::GetCMakeCommand(), cmStrCat("-DPDB_PREFIX=", pdb_prefix), "-P", @@ -2668,14 +2668,16 @@ void cmLocalGenerator::AddPchDependencies(cmGeneratorTarget* target) if (this->GetGlobalGenerator()->IsVisualStudio()) { this->AddCustomCommandToTarget( target->GetName(), outputs, no_deps, commandLines, - cmCustomCommandType::PRE_BUILD, no_message, - no_current_dir); + cmCustomCommandType::PRE_BUILD, no_message, no_current_dir, + true, false, "", "", false, + cmObjectLibraryCommands::Reject, stdPipesUTF8); } else { cmImplicitDependsList no_implicit_depends; cmSourceFile* copy_rule = this->AddCustomCommandToOutput( outputs, no_byproducts, no_deps, no_main_dependency, no_implicit_depends, commandLines, no_message, - no_current_dir); + no_current_dir, false, true, false, false, "", "", + stdPipesUTF8); if (copy_rule) { target->AddSource(copy_rule->ResolveFullPath()); @@ -3389,11 +3391,12 @@ std::string cmLocalGenerator::GetObjectFileNameWithoutTarget( // Select a nice-looking reference to the source file to construct // the object file name. std::string objectName; + // XXX(clang-tidy): https://bugs.llvm.org/show_bug.cgi?id=44165 + // NOLINTNEXTLINE(bugprone-branch-clone) if ((relSource && !relBinary) || (subSource && !subBinary)) { objectName = relFromSource; - } else if ((relBinary && !relSource) || (subBinary && !subSource)) { - objectName = relFromBinary; - } else if (relFromBinary.length() < relFromSource.length()) { + } else if ((relBinary && !relSource) || (subBinary && !subSource) || + relFromBinary.length() < relFromSource.length()) { objectName = relFromBinary; } else { objectName = relFromSource; @@ -3552,7 +3555,6 @@ bool cmLocalGenerator::NeedBackwardsCompatibility_2_4() break; case cmPolicies::NEW: // New behavior is to ignore the variable. - return false; case cmPolicies::REQUIRED_IF_USED: case cmPolicies::REQUIRED_ALWAYS: // This will never be the case because the only way to require @@ -3732,7 +3734,7 @@ cmSourceFile* AddCustomCommand( const cmCustomCommandLines& commandLines, const char* comment, const char* workingDir, bool replace, bool escapeOldStyle, bool uses_terminal, bool command_expand_lists, const std::string& depfile, - const std::string& job_pool) + const std::string& job_pool, bool stdPipesUTF8) { cmMakefile* mf = lg.GetMakefile(); @@ -3794,7 +3796,8 @@ cmSourceFile* AddCustomCommand( } std::unique_ptr<cmCustomCommand> cc = cm::make_unique<cmCustomCommand>( - outputs, byproducts, depends2, commandLines, lfbt, comment, workingDir); + outputs, byproducts, depends2, commandLines, lfbt, comment, workingDir, + stdPipesUTF8); cc->SetEscapeOldStyle(escapeOldStyle); cc->SetEscapeAllowMakeVars(true); cc->SetImplicitDepends(implicit_depends); @@ -3821,7 +3824,7 @@ void AddCustomCommandToTarget(cmLocalGenerator& lg, const char* workingDir, bool escapeOldStyle, bool uses_terminal, const std::string& depfile, const std::string& job_pool, - bool command_expand_lists) + bool command_expand_lists, bool stdPipesUTF8) { cmMakefile* mf = lg.GetMakefile(); @@ -3831,7 +3834,7 @@ void AddCustomCommandToTarget(cmLocalGenerator& lg, // Add the command to the appropriate build step for the target. std::vector<std::string> no_output; cmCustomCommand cc(no_output, byproducts, depends, commandLines, lfbt, - comment, workingDir); + comment, workingDir, stdPipesUTF8); cc.SetEscapeOldStyle(escapeOldStyle); cc.SetEscapeAllowMakeVars(true); cc.SetUsesTerminal(uses_terminal); @@ -3862,7 +3865,7 @@ cmSourceFile* AddCustomCommandToOutput( const cmCustomCommandLines& commandLines, const char* comment, const char* workingDir, bool replace, bool escapeOldStyle, bool uses_terminal, bool command_expand_lists, const std::string& depfile, - const std::string& job_pool) + const std::string& job_pool, bool stdPipesUTF8) { // Always create the output sources and mark them generated. CreateGeneratedSources(lg, outputs, origin, lfbt); @@ -3871,7 +3874,7 @@ cmSourceFile* AddCustomCommandToOutput( return AddCustomCommand( lg, lfbt, outputs, byproducts, depends, main_dependency, implicit_depends, commandLines, comment, workingDir, replace, escapeOldStyle, uses_terminal, - command_expand_lists, depfile, job_pool); + command_expand_lists, depfile, job_pool, stdPipesUTF8); } void AppendCustomCommandToOutput(cmLocalGenerator& lg, @@ -3907,7 +3910,7 @@ void AddUtilityCommand(cmLocalGenerator& lg, const cmListFileBacktrace& lfbt, const cmCustomCommandLines& commandLines, bool escapeOldStyle, const char* comment, bool uses_terminal, bool command_expand_lists, - const std::string& job_pool) + const std::string& job_pool, bool stdPipesUTF8) { // Always create the byproduct sources and mark them generated. CreateGeneratedSource(lg, force.Name, origin, lfbt); @@ -3924,7 +3927,7 @@ void AddUtilityCommand(cmLocalGenerator& lg, const cmListFileBacktrace& lfbt, lg, lfbt, { force.Name }, byproducts, depends, no_main_dependency, no_implicit_depends, commandLines, comment, workingDir, /*replace=*/false, escapeOldStyle, uses_terminal, command_expand_lists, /*depfile=*/"", - job_pool); + job_pool, stdPipesUTF8); if (rule) { lg.GetMakefile()->AddTargetByproducts(target, byproducts); } diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h index 71cc63e..5fb9337 100644 --- a/Source/cmLocalGenerator.h +++ b/Source/cmLocalGenerator.h @@ -297,7 +297,8 @@ public: const char* comment, const char* workingDir, bool escapeOldStyle = true, bool uses_terminal = false, const std::string& depfile = "", const std::string& job_pool = "", bool command_expand_lists = false, - cmObjectLibraryCommands objLibCommands = cmObjectLibraryCommands::Reject); + cmObjectLibraryCommands objLibCommands = cmObjectLibraryCommands::Reject, + bool stdPipesUTF8 = false); /** * Add a custom command to a source file. @@ -308,7 +309,8 @@ public: const cmCustomCommandLines& commandLines, const char* comment, const char* workingDir, bool replace = false, bool escapeOldStyle = true, bool uses_terminal = false, bool command_expand_lists = false, - const std::string& depfile = "", const std::string& job_pool = ""); + const std::string& depfile = "", const std::string& job_pool = "", + bool stdPipesUTF8 = false); cmSourceFile* AddCustomCommandToOutput( const std::vector<std::string>& outputs, const std::vector<std::string>& byproducts, @@ -318,7 +320,8 @@ public: const cmCustomCommandLines& commandLines, const char* comment, const char* workingDir, bool replace = false, bool escapeOldStyle = true, bool uses_terminal = false, bool command_expand_lists = false, - const std::string& depfile = "", const std::string& job_pool = ""); + const std::string& depfile = "", const std::string& job_pool = "", + bool stdPipesUTF8 = false); /** * Add a utility to the build. A utility target is a command that is run @@ -330,7 +333,8 @@ public: const std::vector<std::string>& depends, const cmCustomCommandLines& commandLines, bool escapeOldStyle = true, const char* comment = nullptr, bool uses_terminal = false, - bool command_expand_lists = false, const std::string& job_pool = ""); + bool command_expand_lists = false, const std::string& job_pool = "", + bool stdPipesUTF8 = false); std::string GetProjectName() const; @@ -548,7 +552,7 @@ void AddCustomCommandToTarget(cmLocalGenerator& lg, const char* workingDir, bool escapeOldStyle, bool uses_terminal, const std::string& depfile, const std::string& job_pool, - bool command_expand_lists); + bool command_expand_lists, bool stdPipesUTF8); cmSourceFile* AddCustomCommandToOutput( cmLocalGenerator& lg, const cmListFileBacktrace& lfbt, @@ -559,7 +563,7 @@ cmSourceFile* AddCustomCommandToOutput( const cmCustomCommandLines& commandLines, const char* comment, const char* workingDir, bool replace, bool escapeOldStyle, bool uses_terminal, bool command_expand_lists, const std::string& depfile, - const std::string& job_pool); + const std::string& job_pool, bool stdPipesUTF8); void AppendCustomCommandToOutput(cmLocalGenerator& lg, const cmListFileBacktrace& lfbt, @@ -576,7 +580,7 @@ void AddUtilityCommand(cmLocalGenerator& lg, const cmListFileBacktrace& lfbt, const cmCustomCommandLines& commandLines, bool escapeOldStyle, const char* comment, bool uses_terminal, bool command_expand_lists, - const std::string& job_pool); + const std::string& job_pool, bool stdPipesUTF8); } #endif diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx index 9148b27..82bbc61 100644 --- a/Source/cmLocalVisualStudio7Generator.cxx +++ b/Source/cmLocalVisualStudio7Generator.cxx @@ -251,14 +251,15 @@ cmSourceFile* cmLocalVisualStudio7Generator::CreateVCProjBuildRule() std::string argB = cmStrCat("-B", this->GetBinaryDirectory()); std::string stampName = cmStrCat(this->GetCurrentBinaryDirectory(), "/CMakeFiles/generate.stamp"); + bool stdPipesUTF8 = true; cmCustomCommandLines commandLines = cmMakeSingleCommandLine({ cmSystemTools::GetCMakeCommand(), argS, argB, "--check-stamp-file", stampName }); std::string comment = cmStrCat("Building Custom Rule ", makefileIn); const char* no_working_directory = nullptr; - this->AddCustomCommandToOutput(stampName, listFiles, makefileIn, - commandLines, comment.c_str(), - no_working_directory, true, false); + this->AddCustomCommandToOutput( + stampName, listFiles, makefileIn, commandLines, comment.c_str(), + no_working_directory, true, false, false, false, "", "", stdPipesUTF8); if (cmSourceFile* file = this->Makefile->GetSource(makefileIn)) { // Finalize the source file path now since we're adding this after // the generator validated all project-named sources. diff --git a/Source/cmLocalVisualStudioGenerator.cxx b/Source/cmLocalVisualStudioGenerator.cxx index 7267976..ebd4f96 100644 --- a/Source/cmLocalVisualStudioGenerator.cxx +++ b/Source/cmLocalVisualStudioGenerator.cxx @@ -102,10 +102,12 @@ cmLocalVisualStudioGenerator::MaybeCreateImplibDir(cmGeneratorTarget* target, std::vector<std::string> no_output; std::vector<std::string> no_byproducts; std::vector<std::string> no_depends; + bool stdPipesUTF8 = true; cmCustomCommandLines commands = cmMakeSingleCommandLine( { cmSystemTools::GetCMakeCommand(), "-E", "make_directory", impDir }); pcc.reset(new cmCustomCommand(no_output, no_byproducts, no_depends, commands, - cmListFileBacktrace(), nullptr, nullptr)); + cmListFileBacktrace(), nullptr, nullptr, + stdPipesUTF8)); pcc->SetEscapeOldStyle(false); pcc->SetEscapeAllowMakeVars(true); return pcc; diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 69f316d..85e7df1 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -24,6 +24,7 @@ #include "cm_jsoncpp_value.h" #include "cm_jsoncpp_writer.h" +#include "cm_static_string_view.hxx" #include "cm_sys_stat.h" #include "cmAlgorithms.h" @@ -1021,7 +1022,7 @@ cmTarget* cmMakefile::AddCustomCommandToTarget( const cmCustomCommandLines& commandLines, cmCustomCommandType type, const char* comment, const char* workingDir, bool escapeOldStyle, bool uses_terminal, const std::string& depfile, const std::string& job_pool, - bool command_expand_lists) + bool command_expand_lists, bool stdPipesUTF8) { cmTarget* t = this->GetCustomCommandTarget( target, cmObjectLibraryCommands::Reject, this->Backtrace); @@ -1039,14 +1040,15 @@ cmTarget* cmMakefile::AddCustomCommandToTarget( cm::optional<std::string> workingStr = MakeOptionalString(workingDir); // Dispatch command creation to allow generator expressions in outputs. - this->AddGeneratorAction([=](cmLocalGenerator& lg, - const cmListFileBacktrace& lfbt) { - BacktraceGuard guard(this->Backtrace, lfbt); - detail::AddCustomCommandToTarget( - lg, lfbt, cmCommandOrigin::Project, t, byproducts, depends, commandLines, - type, GetCStrOrNull(commentStr), GetCStrOrNull(workingStr), - escapeOldStyle, uses_terminal, depfile, job_pool, command_expand_lists); - }); + this->AddGeneratorAction( + [=](cmLocalGenerator& lg, const cmListFileBacktrace& lfbt) { + BacktraceGuard guard(this->Backtrace, lfbt); + detail::AddCustomCommandToTarget( + lg, lfbt, cmCommandOrigin::Project, t, byproducts, depends, + commandLines, type, GetCStrOrNull(commentStr), + GetCStrOrNull(workingStr), escapeOldStyle, uses_terminal, depfile, + job_pool, command_expand_lists, stdPipesUTF8); + }); return t; } @@ -1057,14 +1059,14 @@ void cmMakefile::AddCustomCommandToOutput( const char* comment, const char* workingDir, const CommandSourceCallback& callback, bool replace, bool escapeOldStyle, bool uses_terminal, bool command_expand_lists, const std::string& depfile, - const std::string& job_pool) + const std::string& job_pool, bool stdPipesUTF8) { std::vector<std::string> no_byproducts; cmImplicitDependsList no_implicit_depends; this->AddCustomCommandToOutput( { output }, no_byproducts, depends, main_dependency, no_implicit_depends, commandLines, comment, workingDir, callback, replace, escapeOldStyle, - uses_terminal, command_expand_lists, depfile, job_pool); + uses_terminal, command_expand_lists, depfile, job_pool, stdPipesUTF8); } void cmMakefile::AddCustomCommandToOutput( @@ -1075,7 +1077,7 @@ void cmMakefile::AddCustomCommandToOutput( const cmCustomCommandLines& commandLines, const char* comment, const char* workingDir, const CommandSourceCallback& callback, bool replace, bool escapeOldStyle, bool uses_terminal, bool command_expand_lists, - const std::string& depfile, const std::string& job_pool) + const std::string& depfile, const std::string& job_pool, bool stdPipesUTF8) { // Make sure there is at least one output. if (outputs.empty()) { @@ -1097,18 +1099,19 @@ void cmMakefile::AddCustomCommandToOutput( cm::optional<std::string> workingStr = MakeOptionalString(workingDir); // Dispatch command creation to allow generator expressions in outputs. - this->AddGeneratorAction([=](cmLocalGenerator& lg, - const cmListFileBacktrace& lfbt) { - BacktraceGuard guard(this->Backtrace, lfbt); - cmSourceFile* sf = detail::AddCustomCommandToOutput( - lg, lfbt, cmCommandOrigin::Project, outputs, byproducts, depends, - main_dependency, implicit_depends, commandLines, - GetCStrOrNull(commentStr), GetCStrOrNull(workingStr), replace, - escapeOldStyle, uses_terminal, command_expand_lists, depfile, job_pool); - if (callback && sf) { - callback(sf); - } - }); + this->AddGeneratorAction( + [=](cmLocalGenerator& lg, const cmListFileBacktrace& lfbt) { + BacktraceGuard guard(this->Backtrace, lfbt); + cmSourceFile* sf = detail::AddCustomCommandToOutput( + lg, lfbt, cmCommandOrigin::Project, outputs, byproducts, depends, + main_dependency, implicit_depends, commandLines, + GetCStrOrNull(commentStr), GetCStrOrNull(workingStr), replace, + escapeOldStyle, uses_terminal, command_expand_lists, depfile, job_pool, + stdPipesUTF8); + if (callback && sf) { + callback(sf); + } + }); } void cmMakefile::AddCustomCommandOldStyle( @@ -1224,7 +1227,7 @@ cmTarget* cmMakefile::AddUtilityCommand( const std::vector<std::string>& depends, const cmCustomCommandLines& commandLines, bool escapeOldStyle, const char* comment, bool uses_terminal, bool command_expand_lists, - const std::string& job_pool) + const std::string& job_pool, bool stdPipesUTF8) { cmTarget* target = this->AddNewUtilityTarget(utilityName, excludeFromAll); @@ -1253,7 +1256,7 @@ cmTarget* cmMakefile::AddUtilityCommand( force, GetCStrOrNull(workingStr), byproducts, depends, commandLines, escapeOldStyle, GetCStrOrNull(commentStr), uses_terminal, - command_expand_lists, job_pool); + command_expand_lists, job_pool, stdPipesUTF8); }); return target; @@ -2513,10 +2516,7 @@ void cmMakefile::ExpandVariablesCMP0019() for (auto l = linkLibs.begin(); l != linkLibs.end(); ++l) { std::string libName = *l; - if (libName == "optimized") { - ++l; - libName = *l; - } else if (libName == "debug") { + if (libName == "optimized"_s || libName == "debug"_s) { ++l; libName = *l; } diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index 9a7eff9..04a1f2d 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -188,7 +188,8 @@ public: const cmCustomCommandLines& commandLines, cmCustomCommandType type, const char* comment, const char* workingDir, bool escapeOldStyle = true, bool uses_terminal = false, const std::string& depfile = "", - const std::string& job_pool = "", bool command_expand_lists = false); + const std::string& job_pool = "", bool command_expand_lists = false, + bool stdPipesUTF8 = false); /** * Called for each file with custom command. @@ -205,7 +206,8 @@ public: const char* workingDir, const CommandSourceCallback& callback = nullptr, bool replace = false, bool escapeOldStyle = true, bool uses_terminal = false, bool command_expand_lists = false, - const std::string& depfile = "", const std::string& job_pool = ""); + const std::string& depfile = "", const std::string& job_pool = "", + bool stdPipesUTF8 = false); void AddCustomCommandToOutput( const std::vector<std::string>& outputs, const std::vector<std::string>& byproducts, @@ -216,7 +218,8 @@ public: const char* workingDir, const CommandSourceCallback& callback = nullptr, bool replace = false, bool escapeOldStyle = true, bool uses_terminal = false, bool command_expand_lists = false, - const std::string& depfile = "", const std::string& job_pool = ""); + const std::string& depfile = "", const std::string& job_pool = "", + bool stdPipesUTF8 = false); void AddCustomCommandOldStyle(const std::string& target, const std::vector<std::string>& outputs, const std::vector<std::string>& depends, @@ -284,7 +287,8 @@ public: const std::vector<std::string>& depends, const cmCustomCommandLines& commandLines, bool escapeOldStyle = true, const char* comment = nullptr, bool uses_terminal = false, - bool command_expand_lists = false, const std::string& job_pool = ""); + bool command_expand_lists = false, const std::string& job_pool = "", + bool stdPipesUTF8 = false); /** * Add a subdirectory to the build. diff --git a/Source/cmPolicies.cxx b/Source/cmPolicies.cxx index 5c8bc98..dea3f8a 100644 --- a/Source/cmPolicies.cxx +++ b/Source/cmPolicies.cxx @@ -72,6 +72,7 @@ static const char* idToVersion(cmPolicies::PolicyID id) #define POLICY_CASE(ID, V_MAJOR, V_MINOR, V_PATCH) \ case cmPolicies::ID: \ return #V_MAJOR "." #V_MINOR "." #V_PATCH; + // NOLINTNEXTLINE(bugprone-branch-clone) CM_FOR_EACH_POLICY_ID_VERSION(POLICY_CASE) #undef POLICY_CASE case cmPolicies::CMPCOUNT: @@ -90,6 +91,7 @@ static bool isPolicyNewerThan(cmPolicies::PolicyID id, unsigned int majorV, (majorV == (V_MAJOR) && minorV + 1 < (V_MINOR) + 1) || \ (majorV == (V_MAJOR) && minorV == (V_MINOR) && \ patchV + 1 < (V_PATCH) + 1)); + // NOLINTNEXTLINE(bugprone-branch-clone) CM_FOR_EACH_POLICY_ID_VERSION(POLICY_CASE) #undef POLICY_CASE case cmPolicies::CMPCOUNT: diff --git a/Source/cmQtAutoGenInitializer.cxx b/Source/cmQtAutoGenInitializer.cxx index a5af810..87f4656 100644 --- a/Source/cmQtAutoGenInitializer.cxx +++ b/Source/cmQtAutoGenInitializer.cxx @@ -1097,6 +1097,7 @@ bool cmQtAutoGenInitializer::InitAutogenTarget() // of fiddling with the include directories std::vector<std::string> configs; this->GlobalGen->GetQtAutoGenConfigs(configs); + bool stdPipesUTF8 = true; cmCustomCommandLines commandLines; for (auto const& config : configs) { commandLines.push_back(cmMakeCommandLine( @@ -1141,7 +1142,7 @@ bool cmQtAutoGenInitializer::InitAutogenTarget() const std::vector<std::string> no_deps; cmCustomCommand cc(no_output, autogenProvides, no_deps, commandLines, this->Makefile->GetBacktrace(), autogenComment.c_str(), - this->Dir.Work.c_str()); + this->Dir.Work.c_str(), stdPipesUTF8); cc.SetEscapeOldStyle(false); cc.SetEscapeAllowMakeVars(true); this->GenTarget->Target->AddPreBuildCommand(std::move(cc)); @@ -1211,7 +1212,8 @@ bool cmQtAutoGenInitializer::InitAutogenTarget() autogenComment.c_str(), this->Dir.Work.c_str(), /*replace=*/false, /*escapeOldStyle=*/false, /*uses_terminal=*/false, - /*command_expand_lists=*/false, this->AutogenTarget.DepFile); + /*command_expand_lists=*/false, this->AutogenTarget.DepFile, "", + stdPipesUTF8); // Alter variables for the autogen target which now merely wraps the // custom command @@ -1282,6 +1284,7 @@ bool cmQtAutoGenInitializer::InitRccTargets() ccDepends.push_back(qrc.QrcFile); ccDepends.push_back(qrc.InfoFile); + bool stdPipesUTF8 = true; cmCustomCommandLines commandLines; if (this->MultiConfig) { // Build for all configurations @@ -1310,7 +1313,8 @@ bool cmQtAutoGenInitializer::InitRccTargets() cmTarget* autoRccTarget = this->LocalGen->AddUtilityCommand( ccName, true, this->Dir.Work.c_str(), ccOutput, ccDepends, - commandLines, false, ccComment.c_str()); + commandLines, false, ccComment.c_str(), false, false, "", + stdPipesUTF8); // Create autogen generator target this->LocalGen->AddGeneratorTarget( @@ -1350,7 +1354,8 @@ bool cmQtAutoGenInitializer::InitRccTargets() this->LocalGen->AddCustomCommandToOutput( ccOutput, ccByproducts, ccDepends, no_main_dependency, no_implicit_depends, commandLines, ccComment.c_str(), - this->Dir.Work.c_str()); + this->Dir.Work.c_str(), false, true, false, false, "", "", + stdPipesUTF8); } // Reconfigure when .qrc file changes this->Makefile->AddCMakeDependFile(qrc.QrcFile); diff --git a/Source/cmRST.cxx b/Source/cmRST.cxx index c39d162..26e93bb 100644 --- a/Source/cmRST.cxx +++ b/Source/cmRST.cxx @@ -166,6 +166,8 @@ void cmRST::ProcessLine(std::string const& line) this->Markup = (line.find_first_not_of(" \t", 2) == std::string::npos ? MarkupEmpty : MarkupNormal); + // XXX(clang-tidy): https://bugs.llvm.org/show_bug.cgi?id=44165 + // NOLINTNEXTLINE(bugprone-branch-clone) if (this->CMakeDirective.find(line)) { // Output cmake domain directives and their content normally. this->NormalLine(line); diff --git a/Source/cmSeparateArgumentsCommand.cxx b/Source/cmSeparateArgumentsCommand.cxx index 52bde7c..cfe3087 100644 --- a/Source/cmSeparateArgumentsCommand.cxx +++ b/Source/cmSeparateArgumentsCommand.cxx @@ -39,6 +39,8 @@ bool cmSeparateArgumentsCommand(std::vector<std::string> const& args, if (doing == DoingVariable) { var = arg; doing = DoingMode; + // This will always clone one of the other blocks. + // NOLINTNEXTLINE(bugprone-branch-clone) } else if (doing == DoingMode && arg == "NATIVE_COMMAND") { #ifdef _WIN32 mode = ModeWindows; diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 063576c..0c4311d 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -238,8 +238,11 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type, !impl->Makefile->GetSafeDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX").empty(); // Check whether we are targeting AIX. - impl->IsAIX = - (impl->Makefile->GetSafeDefinition("CMAKE_SYSTEM_NAME") == "AIX"); + { + std::string const& systemName = + impl->Makefile->GetSafeDefinition("CMAKE_SYSTEM_NAME"); + impl->IsAIX = (systemName == "AIX" || systemName == "OS400"); + } // Check whether we are targeting an Android platform. impl->IsAndroid = diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index ec7fe96..c5ed9f9 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -1404,6 +1404,9 @@ void cmVisualStudio10TargetGenerator::WriteCustomRule( spe2 = cm::make_unique<Elem>(*spe1, "CustomBuild"); this->WriteSource(*spe2, source); spe2->SetHasElements(); + if (command.GetStdPipesUTF8()) { + this->WriteStdOutEncodingUtf8(*spe2); + } } else { Elem e1(e0, "ItemGroup"); Elem e2(e1, "None"); @@ -4048,6 +4051,7 @@ void cmVisualStudio10TargetGenerator::WriteEvent( std::string script; const char* pre = ""; std::string comment; + bool stdPipesUTF8 = false; for (cmCustomCommand const& cc : commands) { cmCustomCommandGenerator ccg(cc, configName, lg); if (!ccg.HasOnlyEmptyCommandLines()) { @@ -4056,11 +4060,16 @@ void cmVisualStudio10TargetGenerator::WriteEvent( script += pre; pre = "\n"; script += lg->ConstructScript(ccg); + + stdPipesUTF8 = stdPipesUTF8 || cc.GetStdPipesUTF8(); } } comment = cmVS10EscapeComment(comment); if (this->ProjectType != csproj) { Elem e2(e1, name); + if (stdPipesUTF8) { + this->WriteStdOutEncodingUtf8(e2); + } e2.Element("Message", comment); e2.Element("Command", script); } else { @@ -4905,3 +4914,8 @@ std::string cmVisualStudio10TargetGenerator::GetCMakeFilePath( return path; } + +void cmVisualStudio10TargetGenerator::WriteStdOutEncodingUtf8(Elem& e1) +{ + e1.Element("StdOutEncoding", "UTF-8"); +} diff --git a/Source/cmVisualStudio10TargetGenerator.h b/Source/cmVisualStudio10TargetGenerator.h index e588de8..4ac5ec0 100644 --- a/Source/cmVisualStudio10TargetGenerator.h +++ b/Source/cmVisualStudio10TargetGenerator.h @@ -184,6 +184,8 @@ private: Elem& e2, const std::map<std::string, std::string>& tags); std::string GetCSharpSourceLink(cmSourceFile const* source); + void WriteStdOutEncodingUtf8(Elem& e1); + private: friend class cmVS10GeneratorOptions; using Options = cmVS10GeneratorOptions; diff --git a/Source/cmake.cxx b/Source/cmake.cxx index 2ec893f..ea1d8ca 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -642,6 +642,8 @@ void cmake::SetArgs(const std::vector<std::string>& args) path = cmSystemTools::CollapseFullPath(path); cmSystemTools::ConvertToUnixSlashes(path); this->SetHomeDirectory(path); + // XXX(clang-tidy): https://bugs.llvm.org/show_bug.cgi?id=44165 + // NOLINTNEXTLINE(bugprone-branch-clone) } else if (cmHasLiteralPrefix(arg, "-O")) { // There is no local generate anymore. Ignore -O option. } else if (cmHasLiteralPrefix(arg, "-B")) { @@ -681,27 +683,16 @@ void cmake::SetArgs(const std::vector<std::string>& args) this->VSSolutionFile = args[++i]; } #endif - else if (cmHasLiteralPrefix(arg, "-D")) { + else if (cmHasLiteralPrefix(arg, "-D") || cmHasLiteralPrefix(arg, "-U") || + cmHasLiteralPrefix(arg, "-C")) { // skip for now - // in case '-D var=val' is given, also skip the next - // in case '-Dvar=val' is given, don't skip the next - if (arg.size() == 2) { - ++i; - } - } else if (cmHasLiteralPrefix(arg, "-U")) { - // skip for now - // in case '-U var' is given, also skip the next - // in case '-Uvar' is given, don't skip the next - if (arg.size() == 2) { - ++i; - } - } else if (cmHasLiteralPrefix(arg, "-C")) { - // skip for now - // in case '-C path' is given, also skip the next - // in case '-Cpath' is given, don't skip the next + // in case '-[DUC] argval' var' is given, also skip the next + // in case '-[DUC]argval' is given, don't skip the next if (arg.size() == 2) { ++i; } + // XXX(clang-tidy): https://bugs.llvm.org/show_bug.cgi?id=44165 + // NOLINTNEXTLINE(bugprone-branch-clone) } else if (cmHasLiteralPrefix(arg, "-P")) { // skip for now i++; diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx index c3bd160..49d04a6 100644 --- a/Source/cmcmd.cxx +++ b/Source/cmcmd.cxx @@ -1972,9 +1972,8 @@ bool cmVSLink::Parse(std::vector<std::string>::const_iterator argBeg, // Parse the link command to extract information we need. for (; arg != argEnd; ++arg) { - if (cmSystemTools::Strucmp(arg->c_str(), "/INCREMENTAL:YES") == 0) { - this->Incremental = true; - } else if (cmSystemTools::Strucmp(arg->c_str(), "/INCREMENTAL") == 0) { + if (cmSystemTools::Strucmp(arg->c_str(), "/INCREMENTAL:YES") == 0 || + cmSystemTools::Strucmp(arg->c_str(), "/INCREMENTAL") == 0) { this->Incremental = true; } else if (cmSystemTools::Strucmp(arg->c_str(), "/MANIFEST:NO") == 0) { this->LinkGeneratesManifest = false; diff --git a/Templates/TestDriver.cxx.in b/Templates/TestDriver.cxx.in index 846a828..053f1ee 100644 --- a/Templates/TestDriver.cxx.in +++ b/Templates/TestDriver.cxx.in @@ -45,7 +45,8 @@ static const int NumTests = CM_CAST(int, (note that it has to be free'd manually) */ static char* lowercase(const char* string) { - char *new_string, *p; + char *new_string; + char *p; size_t stringSize; stringSize = CM_CAST(size_t, strlen(string) + 1); @@ -63,7 +64,9 @@ static char* lowercase(const char* string) int main(int ac, char* av[]) { - int i, testNum = 0, partial_match; + int i; + int testNum = 0; + int partial_match; char *arg; int testToRun = -1; diff --git a/Tests/CMakeTests/ListTest.cmake.in b/Tests/CMakeTests/ListTest.cmake.in index f517e64..785f41d 100644 --- a/Tests/CMakeTests/ListTest.cmake.in +++ b/Tests/CMakeTests/ListTest.cmake.in @@ -85,6 +85,9 @@ set(result ken bill andy brad) list(SORT result) TEST("SORT result" "andy;bill;brad;ken") +list(SORT result COMPARE NATURAL) +TEST("SORT result COMPARE NATURAL" "andy;bill;brad;ken") + set(result andy bill brad ken) list(REVERSE result) TEST("REVERSE result" "ken;brad;bill;andy") @@ -104,6 +107,26 @@ TEST("REVERSE empty result" "") list(SORT result) TEST("SORT empty result" "") +list(SORT result COMPARE NATURAL) +TEST("SORT result COMPARE NATURAL" "") + +set(result 1.1 10.0 11.0 12.0 12.1 2.0 2.1 3.0 3.1 3.2 8.0 9.0) + +list(SORT result COMPARE NATURAL) +TEST("SORT result COMPARE NATURAL" "1.1;2.0;2.1;3.0;3.1;3.2;8.0;9.0;10.0;11.0;12.0;12.1") + +list(SORT result) +TEST("SORT result" "1.1;10.0;11.0;12.0;12.1;2.0;2.1;3.0;3.1;3.2;8.0;9.0") + +list(SORT result COMPARE NATURAL ORDER DESCENDING) +TEST("SORT result COMPARE NATURAL ORDER DESCENDING" "12.1;12.0;11.0;10.0;9.0;8.0;3.2;3.1;3.0;2.1;2.0;1.1") + +set(result b-1.1 a-10.0 c-2.0 d 1 00 0) + +list(SORT result COMPARE NATURAL) +TEST("SORT result COMPARE NATURAL" "00;0;1;a-10.0;b-1.1;c-2.0;d") + + # these trigger top-level condition foreach(cmd IN ITEMS Append Find Get Insert Length Reverse Remove_At Remove_Duplicates Remove_Item Sort) set(${cmd}-No-Arguments-RESULT 1) diff --git a/Tests/RunCMake/exit_code.c b/Tests/RunCMake/exit_code.c index 3eba019..9fa8eca 100644 --- a/Tests/RunCMake/exit_code.c +++ b/Tests/RunCMake/exit_code.c @@ -21,7 +21,8 @@ int main(int argc, const char* argv[]) } if (strcmp(str, substring_success) == 0) { return EXIT_SUCCESS; - } else if (strcmp(str, substring_failure) == 0) { + } + if (strcmp(str, substring_failure) == 0) { return EXIT_FAILURE; } fprintf(stderr, "Failed to find string '%s' in '%s'\n", substring_success, diff --git a/Tests/RunCMake/pseudo_cppcheck.c b/Tests/RunCMake/pseudo_cppcheck.c index 5b1531b..e80620c 100644 --- a/Tests/RunCMake/pseudo_cppcheck.c +++ b/Tests/RunCMake/pseudo_cppcheck.c @@ -11,7 +11,8 @@ int main(int argc, char* argv[]) fprintf(stdout, "stdout from bad command line arg '-bad'\n"); fprintf(stderr, "stderr from bad command line arg '-bad'\n"); return 1; - } else if (strcmp(argv[i], "-error") == 0) { + } + if (strcmp(argv[i], "-error") == 0) { // The real cppcheck allows to set the exitcode with --error-exitcode result = 5; } |