summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
Diffstat (limited to 'Source')
-rw-r--r--Source/CMakeLists.txt3
-rw-r--r--Source/CMakeVersion.cmake2
-rw-r--r--Source/CMakeVersion.rc.in11
-rw-r--r--Source/CMakeVersionCompute.cmake10
-rw-r--r--Source/CPack/cmCPackGenerator.cxx15
-rw-r--r--Source/CPack/cmCPackPKGGenerator.cxx2
-rw-r--r--Source/CTest/cmCTestBatchTestHandler.cxx123
-rw-r--r--Source/CTest/cmCTestBatchTestHandler.h33
-rw-r--r--Source/CTest/cmCTestRunTest.cxx8
-rw-r--r--Source/CTest/cmCTestTestHandler.cxx5
-rw-r--r--Source/CTest/cmCTestTestHandler.h1
-rw-r--r--Source/Checks/cm_cxx_attribute_fallthrough.cxx11
-rw-r--r--Source/Checks/cm_cxx_fallthrough.cxx11
-rw-r--r--Source/Checks/cm_cxx_features.cmake7
-rw-r--r--Source/Checks/cm_cxx_gnu_fallthrough.cxx11
-rw-r--r--Source/Modules/OverrideC.cmake3
-rw-r--r--Source/Modules/OverrideCXX.cmake3
-rw-r--r--Source/QtDialog/RegexExplorer.cxx4
-rw-r--r--Source/cmCTest.cxx4
-rw-r--r--Source/cmCTest.h4
-rw-r--r--Source/cmConfigure.cmake.h.in13
-rw-r--r--Source/cmConnection.cxx19
-rw-r--r--Source/cmConnection.h5
-rw-r--r--Source/cmExtraCodeBlocksGenerator.cxx7
-rw-r--r--Source/cmExtraSublimeTextGenerator.cxx19
-rw-r--r--Source/cmGeneratorExpression.h50
-rw-r--r--Source/cmGlobalGenerator.h4
-rw-r--r--Source/cmGlobalVisualStudioGenerator.h2
-rw-r--r--Source/cmGlobalXCodeGenerator.cxx68
-rw-r--r--Source/cmIncludeExternalMSProjectCommand.cxx5
-rw-r--r--Source/cmLocalNinjaGenerator.cxx3
-rw-r--r--Source/cmLocalVisualStudio7Generator.cxx13
-rw-r--r--Source/cmMakefileTargetGenerator.cxx22
-rw-r--r--Source/cmNinjaTargetGenerator.cxx34
-rw-r--r--Source/cmPipeConnection.cxx51
-rw-r--r--Source/cmPipeConnection.h4
-rw-r--r--Source/cmQtAutoGeneratorInitializer.cxx45
-rw-r--r--Source/cmServer.cxx74
-rw-r--r--Source/cmServer.h10
-rw-r--r--Source/cmServerConnection.cxx71
-rw-r--r--Source/cmServerConnection.h6
-rw-r--r--Source/cmServerDictionary.h5
-rw-r--r--Source/cmServerProtocol.cxx69
-rw-r--r--Source/cmStandardLexer.h2
-rw-r--r--Source/cmTarget.cxx1
-rw-r--r--Source/cmTargetLinkLibrariesCommand.cxx175
-rw-r--r--Source/cmTargetLinkLibrariesCommand.h3
-rw-r--r--Source/cmTargetPropertyComputer.cxx7
-rw-r--r--Source/cmUVHandlePtr.cxx227
-rw-r--r--Source/cmUVHandlePtr.h222
-rw-r--r--Source/cmVisualStudio10TargetGenerator.cxx45
-rw-r--r--Source/cm_thread.hxx38
-rw-r--r--Source/cmcmd.cxx6
-rw-r--r--Source/kwsys/CMakeLists.txt13
-rw-r--r--Source/kwsys/Configure.hxx.in26
-rw-r--r--Source/kwsys/ConsoleBuf.hxx.in2
-rw-r--r--Source/kwsys/RegularExpression.cxx189
-rw-r--r--Source/kwsys/RegularExpression.hxx.in227
-rw-r--r--Source/kwsys/hash_map.hxx.in2
-rw-r--r--Source/kwsys/hash_set.hxx.in2
-rw-r--r--Source/kwsys/hashtable.hxx.in13
-rw-r--r--Source/kwsys/testConfigure.cxx30
62 files changed, 1283 insertions, 817 deletions
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index 33ab093..7031d5a 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -348,6 +348,8 @@ set(SRCS
cmTestGenerator.cxx
cmTestGenerator.h
cmUuid.cxx
+ cmUVHandlePtr.cxx
+ cmUVHandlePtr.h
cmVariableWatch.cxx
cmVariableWatch.h
cmVersion.cxx
@@ -800,7 +802,6 @@ include_directories(
#
set(CTEST_SRCS cmCTest.cxx
CTest/cmProcess.cxx
- CTest/cmCTestBatchTestHandler.cxx
CTest/cmCTestBuildAndTestHandler.cxx
CTest/cmCTestBuildCommand.cxx
CTest/cmCTestBuildHandler.cxx
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 500a872..a28378a 100644
--- a/Source/CMakeVersion.cmake
+++ b/Source/CMakeVersion.cmake
@@ -1,5 +1,5 @@
# CMake version number components.
set(CMake_VERSION_MAJOR 3)
set(CMake_VERSION_MINOR 10)
-set(CMake_VERSION_PATCH 20171128)
+set(CMake_VERSION_PATCH 20171212)
#set(CMake_VERSION_RC 1)
diff --git a/Source/CMakeVersion.rc.in b/Source/CMakeVersion.rc.in
index f4ca3d5..22b4a36 100644
--- a/Source/CMakeVersion.rc.in
+++ b/Source/CMakeVersion.rc.in
@@ -1,11 +1,14 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
-#define VER_FILEVERSION @CMake_VERSION_MAJOR@,@CMake_VERSION_MINOR@,@CMake_VERSION_PATCH@
-#define VER_FILEVERSION_STR "@CMake_VERSION_MAJOR@.@CMake_VERSION_MINOR@.@CMake_VERSION_PATCH@\0"
+#define VER_FILEVERSION @CMake_RCVERSION@
+#define VER_FILEVERSION_STR "@CMake_RCVERSION_STR@\0"
-#define VER_PRODUCTVERSION @CMake_VERSION_MAJOR@,@CMake_VERSION_MINOR@,@CMake_VERSION_PATCH@
-#define VER_PRODUCTVERSION_STR "@CMake_VERSION@\0"
+#define VER_PRODUCTVERSION @CMake_RCVERSION@
+#define VER_PRODUCTVERSION_STR "@CMake_RCVERSION_STR@\0"
+
+/* Version-information resource identifier. */
+#define VS_VERSION_INFO 1
VS_VERSION_INFO VERSIONINFO
FILEVERSION VER_FILEVERSION
diff --git a/Source/CMakeVersionCompute.cmake b/Source/CMakeVersionCompute.cmake
index d9218d7..79264ed 100644
--- a/Source/CMakeVersionCompute.cmake
+++ b/Source/CMakeVersionCompute.cmake
@@ -27,3 +27,13 @@ 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 ${CMake_VERSION_MAJOR},${CMake_VERSION_MINOR},${CMAKE_MATCH_1},${CMAKE_MATCH_2})
+else()
+ set(CMake_RCVERSION ${CMake_VERSION_MAJOR},${CMake_VERSION_MINOR},${CMake_VERSION_PATCH})
+endif()
+set(CMake_RCVERSION_STR ${CMake_VERSION})
diff --git a/Source/CPack/cmCPackGenerator.cxx b/Source/CPack/cmCPackGenerator.cxx
index be75a9f..ea0e899 100644
--- a/Source/CPack/cmCPackGenerator.cxx
+++ b/Source/CPack/cmCPackGenerator.cxx
@@ -17,6 +17,7 @@
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
#include "cmStateSnapshot.h"
+#include "cmVersion.h"
#include "cmWorkingDirectory.h"
#include "cmXMLSafe.h"
#include "cmake.h"
@@ -988,10 +989,16 @@ int cmCPackGenerator::DoPackage()
*/
packageFileNames.push_back(tempPackageFileName ? tempPackageFileName : "");
toplevel = tempDirectory;
- if (!this->PackageFiles() || cmSystemTools::GetErrorOccuredFlag()) {
- cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem compressing the directory"
- << std::endl);
- return 0;
+ { // scope that enables package generators to run internal scripts with
+ // latest CMake policies enabled
+ cmMakefile::ScopePushPop pp{ this->MakefileMap };
+ this->MakefileMap->SetPolicyVersion(cmVersion::GetCMakeVersion());
+
+ if (!this->PackageFiles() || cmSystemTools::GetErrorOccuredFlag()) {
+ cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem compressing the directory"
+ << std::endl);
+ return 0;
+ }
}
/* Prepare checksum algorithm*/
diff --git a/Source/CPack/cmCPackPKGGenerator.cxx b/Source/CPack/cmCPackPKGGenerator.cxx
index 4f5b2a0..9ea8540 100644
--- a/Source/CPack/cmCPackPKGGenerator.cxx
+++ b/Source/CPack/cmCPackPKGGenerator.cxx
@@ -189,7 +189,7 @@ void cmCPackPKGGenerator::CreateChoice(const cmCPackComponent& component,
// This way, selecting C will automatically select everything it depends
// on (B and A), while selecting something that depends on C--either D
// or E--will automatically cause C to get selected.
- std::ostringstream selected("my.choice.selected");
+ std::ostringstream selected("my.choice.selected", std::ios_base::ate);
std::set<const cmCPackComponent*> visited;
AddDependencyAttributes(component, visited, selected);
visited.clear();
diff --git a/Source/CTest/cmCTestBatchTestHandler.cxx b/Source/CTest/cmCTestBatchTestHandler.cxx
deleted file mode 100644
index 2eed8be..0000000
--- a/Source/CTest/cmCTestBatchTestHandler.cxx
+++ /dev/null
@@ -1,123 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#include "cmCTestBatchTestHandler.h"
-
-#include "cmCTest.h"
-#include "cmCTestMultiProcessHandler.h"
-#include "cmCTestTestHandler.h"
-#include "cmProcess.h"
-#include "cmSystemTools.h"
-
-#include <map>
-#include <utility>
-#include <vector>
-
-cmCTestBatchTestHandler::~cmCTestBatchTestHandler()
-{
-}
-
-void cmCTestBatchTestHandler::RunTests()
-{
- this->WriteBatchScript();
- this->SubmitBatchScript();
-}
-
-void cmCTestBatchTestHandler::WriteBatchScript()
-{
- this->Script = this->CTest->GetBinaryDir() + "/Testing/CTestBatch.txt";
- cmsys::ofstream fout;
- fout.open(this->Script.c_str());
- fout << "#!/bin/sh\n";
-
- for (auto const& t : this->Tests) {
- this->WriteSrunArgs(t.first, fout);
- this->WriteTestCommand(t.first, fout);
- fout << "\n";
- }
- fout.flush();
- fout.close();
-}
-
-void cmCTestBatchTestHandler::WriteSrunArgs(int test, std::ostream& fout)
-{
- cmCTestTestHandler::cmCTestTestProperties* properties =
- this->Properties[test];
-
- fout << "srun ";
- // fout << "--jobid=" << test << " ";
- fout << "-J=" << properties->Name << " ";
-
- // Write dependency information
- /*if(!this->Tests[test].empty())
- {
- fout << "-P=afterany";
- for(TestSet::iterator i = this->Tests[test].begin();
- i != this->Tests[test].end(); ++i)
- {
- fout << ":" << *i;
- }
- fout << " ";
- }*/
- if (properties->RunSerial) {
- fout << "--exclusive ";
- }
- if (properties->Processors > 1) {
- fout << "-n" << properties->Processors << " ";
- }
-}
-
-void cmCTestBatchTestHandler::WriteTestCommand(int test, std::ostream& fout)
-{
- std::vector<std::string> args = this->Properties[test]->Args;
- std::vector<std::string> processArgs;
- std::string command;
-
- command = this->TestHandler->FindTheExecutable(args[1].c_str());
- command = cmSystemTools::ConvertToOutputPath(command.c_str());
-
- // Prepends memcheck args to our command string if this is a memcheck
- this->TestHandler->GenerateTestCommand(processArgs, test);
- processArgs.push_back(command);
-
- for (std::string const& arg : processArgs) {
- fout << arg << " ";
- }
-
- std::vector<std::string>::iterator i = args.begin();
- ++i; // the test name
- ++i; // the executable (command)
- if (args.size() > 2) {
- fout << "'";
- }
- while (i != args.end()) {
- fout << "\"" << *i << "\""; // args to the test executable
- ++i;
-
- if (i == args.end() && args.size() > 2) {
- fout << "'";
- }
- fout << " ";
- }
- // TODO ZACH build TestResult.FullCommandLine
- // this->TestResult.FullCommandLine = this->TestCommand;
-}
-
-void cmCTestBatchTestHandler::SubmitBatchScript()
-{
- cmProcess sbatch;
- std::vector<std::string> args;
- args.push_back(this->Script);
- args.push_back("-o");
- args.push_back(this->CTest->GetBinaryDir() + "/Testing/CTestBatch.txt");
-
- sbatch.SetCommand("sbatch");
- sbatch.SetCommandArguments(args);
- /*if(sbatch.StartProcess())
- {
- //success condition
- }
- else
- {
- //fail condition
- }*/
-}
diff --git a/Source/CTest/cmCTestBatchTestHandler.h b/Source/CTest/cmCTestBatchTestHandler.h
deleted file mode 100644
index 42f87bd..0000000
--- a/Source/CTest/cmCTestBatchTestHandler.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#ifndef cmCTestBatchTestHandler_h
-#define cmCTestBatchTestHandler_h
-
-#include "cmConfigure.h" // IWYU pragma: keep
-
-#include "cmCTestMultiProcessHandler.h"
-#include "cmsys/FStream.hxx"
-#include <string>
-
-/** \class cmCTestBatchTestHandler
- * \brief run parallel ctest
- *
- * cmCTestBatchTestHandler
- */
-class cmCTestBatchTestHandler : public cmCTestMultiProcessHandler
-{
-public:
- ~cmCTestBatchTestHandler() override;
- void RunTests() override;
-
-protected:
- void WriteBatchScript();
- void WriteSrunArgs(int test, std::ostream& fout);
- void WriteTestCommand(int test, std::ostream& fout);
-
- void SubmitBatchScript();
-
- std::string Script;
-};
-
-#endif
diff --git a/Source/CTest/cmCTestRunTest.cxx b/Source/CTest/cmCTestRunTest.cxx
index dcb17d0..dbdefae 100644
--- a/Source/CTest/cmCTestRunTest.cxx
+++ b/Source/CTest/cmCTestRunTest.cxx
@@ -438,8 +438,6 @@ bool cmCTestRunTest::StartTest(size_t total)
return false;
}
- this->ComputeArguments();
- std::vector<std::string>& args = this->TestProperties->Args;
this->TestResult.Properties = this->TestProperties;
this->TestResult.ExecutionTime = std::chrono::duration<double>::zero();
this->TestResult.CompressOutput = false;
@@ -450,6 +448,10 @@ bool cmCTestRunTest::StartTest(size_t total)
this->TestResult.Name = this->TestProperties->Name;
this->TestResult.Path = this->TestProperties->Directory;
+ // Check for failed fixture dependencies before we even look at the command
+ // arguments because if we are not going to run the test, the command and
+ // its arguments are irrelevant. This matters for the case where a fixture
+ // dependency might be creating the executable we want to run.
if (!this->FailedDependencies.empty()) {
this->TestProcess = new cmProcess;
std::string msg = "Failed test dependencies:";
@@ -465,6 +467,8 @@ bool cmCTestRunTest::StartTest(size_t total)
return false;
}
+ this->ComputeArguments();
+ std::vector<std::string>& args = this->TestProperties->Args;
if (args.size() >= 2 && args[1] == "NOT_AVAILABLE") {
this->TestProcess = new cmProcess;
std::string msg;
diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx
index e5a0503..4c7cefb 100644
--- a/Source/CTest/cmCTestTestHandler.cxx
+++ b/Source/CTest/cmCTestTestHandler.cxx
@@ -19,7 +19,6 @@
#include "cmAlgorithms.h"
#include "cmCTest.h"
-#include "cmCTestBatchTestHandler.h"
#include "cmCTestMultiProcessHandler.h"
#include "cmCommand.h"
#include "cmGeneratedFileStream.h"
@@ -1205,9 +1204,7 @@ void cmCTestTestHandler::ProcessDirectory(std::vector<std::string>& passed,
this->StartTestTime = std::chrono::system_clock::now();
auto elapsed_time_start = std::chrono::steady_clock::now();
- cmCTestMultiProcessHandler* parallel = this->CTest->GetBatchJobs()
- ? new cmCTestBatchTestHandler
- : new cmCTestMultiProcessHandler;
+ cmCTestMultiProcessHandler* parallel = new cmCTestMultiProcessHandler;
parallel->SetCTest(this->CTest);
parallel->SetParallelLevel(this->CTest->GetParallelLevel());
parallel->SetTestHandler(this);
diff --git a/Source/CTest/cmCTestTestHandler.h b/Source/CTest/cmCTestTestHandler.h
index 19b345e..4fb067a 100644
--- a/Source/CTest/cmCTestTestHandler.h
+++ b/Source/CTest/cmCTestTestHandler.h
@@ -29,7 +29,6 @@ class cmCTestTestHandler : public cmCTestGenericHandler
{
friend class cmCTestRunTest;
friend class cmCTestMultiProcessHandler;
- friend class cmCTestBatchTestHandler;
public:
typedef cmCTestGenericHandler Superclass;
diff --git a/Source/Checks/cm_cxx_attribute_fallthrough.cxx b/Source/Checks/cm_cxx_attribute_fallthrough.cxx
deleted file mode 100644
index 50605b7..0000000
--- a/Source/Checks/cm_cxx_attribute_fallthrough.cxx
+++ /dev/null
@@ -1,11 +0,0 @@
-int main(int argc, char* [])
-{
- int i = 3;
- switch (argc) {
- case 1:
- i = 0;
- __attribute__((fallthrough));
- default:
- return i;
- }
-}
diff --git a/Source/Checks/cm_cxx_fallthrough.cxx b/Source/Checks/cm_cxx_fallthrough.cxx
deleted file mode 100644
index 2825bed..0000000
--- a/Source/Checks/cm_cxx_fallthrough.cxx
+++ /dev/null
@@ -1,11 +0,0 @@
-int main(int argc, char* [])
-{
- int i = 3;
- switch (argc) {
- case 1:
- i = 0;
- [[fallthrough]];
- default:
- return i;
- }
-}
diff --git a/Source/Checks/cm_cxx_features.cmake b/Source/Checks/cm_cxx_features.cmake
index a30a5e6..2704c40 100644
--- a/Source/Checks/cm_cxx_features.cmake
+++ b/Source/Checks/cm_cxx_features.cmake
@@ -41,13 +41,6 @@ function(cm_check_cxx_feature name)
endif()
endfunction()
-cm_check_cxx_feature(fallthrough)
-if(NOT CMake_HAVE_CXX_FALLTHROUGH)
- cm_check_cxx_feature(gnu_fallthrough)
- if(NOT CMake_HAVE_CXX_GNU_FALLTHROUGH)
- cm_check_cxx_feature(attribute_fallthrough)
- endif()
-endif()
cm_check_cxx_feature(make_unique)
if(CMake_HAVE_CXX_MAKE_UNIQUE)
set(CMake_HAVE_CXX_UNIQUE_PTR 1)
diff --git a/Source/Checks/cm_cxx_gnu_fallthrough.cxx b/Source/Checks/cm_cxx_gnu_fallthrough.cxx
deleted file mode 100644
index ebc15f4..0000000
--- a/Source/Checks/cm_cxx_gnu_fallthrough.cxx
+++ /dev/null
@@ -1,11 +0,0 @@
-int main(int argc, char* [])
-{
- int i = 3;
- switch (argc) {
- case 1:
- i = 0;
- [[gnu::fallthrough]];
- default:
- return i;
- }
-}
diff --git a/Source/Modules/OverrideC.cmake b/Source/Modules/OverrideC.cmake
new file mode 100644
index 0000000..f8299ad
--- /dev/null
+++ b/Source/Modules/OverrideC.cmake
@@ -0,0 +1,3 @@
+if("${CMAKE_SYSTEM_NAME};${CMAKE_C_COMPILER_ID}" STREQUAL "AIX;GNU")
+ string(APPEND CMAKE_C_FLAGS_INIT " -pthread")
+endif()
diff --git a/Source/Modules/OverrideCXX.cmake b/Source/Modules/OverrideCXX.cmake
new file mode 100644
index 0000000..13689e2
--- /dev/null
+++ b/Source/Modules/OverrideCXX.cmake
@@ -0,0 +1,3 @@
+if("${CMAKE_SYSTEM_NAME};${CMAKE_CXX_COMPILER_ID}" STREQUAL "AIX;GNU")
+ string(APPEND CMAKE_CXX_FLAGS_INIT " -pthread")
+endif()
diff --git a/Source/QtDialog/RegexExplorer.cxx b/Source/QtDialog/RegexExplorer.cxx
index abed70e..cb67f85 100644
--- a/Source/QtDialog/RegexExplorer.cxx
+++ b/Source/QtDialog/RegexExplorer.cxx
@@ -8,7 +8,7 @@ RegexExplorer::RegexExplorer(QWidget* p)
{
this->setupUi(this);
- for (int i = 1; i < cmsys::RegularExpression::NSUBEXP; ++i) {
+ for (int i = 1; i < cmsys::RegularExpressionMatch::NSUBEXP; ++i) {
matchNumber->addItem(QString("Match %1").arg(QString::number(i)),
QVariant(i));
}
@@ -105,7 +105,7 @@ void RegexExplorer::on_matchNumber_currentIndexChanged(int index)
QVariant itemData = matchNumber->itemData(index);
int idx = itemData.toInt();
- if (idx < 1 || idx >= cmsys::RegularExpression::NSUBEXP) {
+ if (idx < 1 || idx >= cmsys::RegularExpressionMatch::NSUBEXP) {
return;
}
diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx
index e48f64a..26e1dcb 100644
--- a/Source/cmCTest.cxx
+++ b/Source/cmCTest.cxx
@@ -260,7 +260,6 @@ cmCTest::cmCTest()
this->TestLoad = 0;
this->SubmitIndex = 0;
this->Failover = false;
- this->BatchJobs = false;
this->ForceNewCTestProcess = false;
this->TomorrowTag = false;
this->Verbose = false;
@@ -1814,9 +1813,6 @@ bool cmCTest::HandleCommandLineArguments(size_t& i,
if (this->CheckArgument(arg, "-V", "--verbose")) {
this->Verbose = true;
}
- if (this->CheckArgument(arg, "-B")) {
- this->BatchJobs = true;
- }
if (this->CheckArgument(arg, "-VV", "--extra-verbose")) {
this->ExtraVerbose = true;
this->Verbose = true;
diff --git a/Source/cmCTest.h b/Source/cmCTest.h
index 418d576..23d71cb 100644
--- a/Source/cmCTest.h
+++ b/Source/cmCTest.h
@@ -429,9 +429,6 @@ public:
void SetFailover(bool failover) { this->Failover = failover; }
bool GetFailover() { return this->Failover; }
- void SetBatchJobs(bool batch = true) { this->BatchJobs = batch; }
- bool GetBatchJobs() { return this->BatchJobs; }
-
bool GetVerbose() { return this->Verbose; }
bool GetExtraVerbose() { return this->ExtraVerbose; }
@@ -477,7 +474,6 @@ private:
bool UseHTTP10;
bool PrintLabels;
bool Failover;
- bool BatchJobs;
bool ForceNewCTestProcess;
diff --git a/Source/cmConfigure.cmake.h.in b/Source/cmConfigure.cmake.h.in
index 9a78aca..c80439b 100644
--- a/Source/cmConfigure.cmake.h.in
+++ b/Source/cmConfigure.cmake.h.in
@@ -19,22 +19,11 @@
#cmakedefine HAVE_UNSETENV
#cmakedefine CMAKE_USE_ELF_PARSER
#cmakedefine CMAKE_USE_MACH_PARSER
-#cmakedefine CMake_HAVE_CXX_FALLTHROUGH
-#cmakedefine CMake_HAVE_CXX_GNU_FALLTHROUGH
-#cmakedefine CMake_HAVE_CXX_ATTRIBUTE_FALLTHROUGH
#cmakedefine CMake_HAVE_CXX_MAKE_UNIQUE
#define CMAKE_BIN_DIR "/@CMAKE_BIN_DIR@"
#define CMAKE_DATA_DIR "/@CMAKE_DATA_DIR@"
-#if defined(CMake_HAVE_CXX_FALLTHROUGH)
-#define CM_FALLTHROUGH [[fallthrough]]
-#elif defined(CMake_HAVE_CXX_GNU_FALLTHROUGH)
-#define CM_FALLTHROUGH [[gnu::fallthrough]]
-#elif defined(CMake_HAVE_CXX_ATTRIBUTE_FALLTHROUGH)
-#define CM_FALLTHROUGH __attribute__((fallthrough))
-#else
-#define CM_FALLTHROUGH
-#endif
+#define CM_FALLTHROUGH cmsys_FALLTHROUGH
#define CM_DISABLE_COPY(Class) \
Class(Class const&) = delete; \
diff --git a/Source/cmConnection.cxx b/Source/cmConnection.cxx
index 28ba12c..50e1936 100644
--- a/Source/cmConnection.cxx
+++ b/Source/cmConnection.cxx
@@ -26,7 +26,7 @@ void cmEventBasedConnection::on_alloc_buffer(uv_handle_t* handle,
void cmEventBasedConnection::on_read(uv_stream_t* stream, ssize_t nread,
const uv_buf_t* buf)
{
- auto conn = reinterpret_cast<cmEventBasedConnection*>(stream->data);
+ auto conn = static_cast<cmEventBasedConnection*>(stream->data);
if (conn) {
if (nread >= 0) {
conn->ReadData(std::string(buf->base, buf->base + nread));
@@ -55,7 +55,7 @@ void cmEventBasedConnection::on_write(uv_write_t* req, int status)
void cmEventBasedConnection::on_new_connection(uv_stream_t* stream, int status)
{
(void)(status);
- auto conn = reinterpret_cast<cmEventBasedConnection*>(stream->data);
+ auto conn = static_cast<cmEventBasedConnection*>(stream->data);
if (conn) {
conn->Connect(stream);
@@ -76,7 +76,7 @@ void cmEventBasedConnection::WriteData(const std::string& _data)
#endif
auto data = _data;
- assert(this->WriteStream);
+ assert(this->WriteStream.get());
if (BufferStrategy) {
data = BufferStrategy->BufferOutMessage(data);
}
@@ -87,8 +87,7 @@ void cmEventBasedConnection::WriteData(const std::string& _data)
req->req.data = this;
req->buf = uv_buf_init(new char[ds], static_cast<unsigned int>(ds));
memcpy(req->buf.base, data.c_str(), ds);
- uv_write(reinterpret_cast<uv_write_t*>(req),
- static_cast<uv_stream_t*>(this->WriteStream), &req->buf, 1,
+ uv_write(reinterpret_cast<uv_write_t*>(req), this->WriteStream, &req->buf, 1,
on_write);
}
@@ -156,13 +155,11 @@ bool cmConnection::OnServeStart(std::string* errString)
bool cmEventBasedConnection::OnConnectionShuttingDown()
{
- if (this->WriteStream) {
+ if (this->WriteStream.get()) {
this->WriteStream->data = nullptr;
}
- if (this->ReadStream) {
- this->ReadStream->data = nullptr;
- }
- this->ReadStream = nullptr;
- this->WriteStream = nullptr;
+
+ WriteStream.reset();
+
return true;
}
diff --git a/Source/cmConnection.h b/Source/cmConnection.h
index ddb7744..ce2d2dc 100644
--- a/Source/cmConnection.h
+++ b/Source/cmConnection.h
@@ -5,6 +5,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
+#include "cmUVHandlePtr.h"
#include "cm_uv.h"
#include <cstddef>
@@ -107,8 +108,6 @@ public:
bool OnConnectionShuttingDown() override;
virtual void OnDisconnect(int errorCode);
- uv_stream_t* ReadStream = nullptr;
- uv_stream_t* WriteStream = nullptr;
static void on_close(uv_handle_t* handle);
@@ -119,6 +118,8 @@ public:
}
protected:
+ cm::uv_stream_ptr WriteStream;
+
std::string RawReadBuffer;
std::unique_ptr<cmConnectionBufferStrategy> BufferStrategy;
diff --git a/Source/cmExtraCodeBlocksGenerator.cxx b/Source/cmExtraCodeBlocksGenerator.cxx
index 76fc8f1..edce330 100644
--- a/Source/cmExtraCodeBlocksGenerator.cxx
+++ b/Source/cmExtraCodeBlocksGenerator.cxx
@@ -642,6 +642,13 @@ void cmExtraCodeBlocksGenerator::AppendTarget(
// Translate the cmake compiler id into the CodeBlocks compiler id
std::string cmExtraCodeBlocksGenerator::GetCBCompilerId(const cmMakefile* mf)
{
+ // allow the user to overwrite the detected compiler
+ std::string userCompiler =
+ mf->GetSafeDefinition("CMAKE_CODEBLOCKS_COMPILER_ID");
+ if (!userCompiler.empty()) {
+ return userCompiler;
+ }
+
// figure out which language to use
// for now care only for C, C++, and Fortran
diff --git a/Source/cmExtraSublimeTextGenerator.cxx b/Source/cmExtraSublimeTextGenerator.cxx
index 3d72ae3..bd1b6bb 100644
--- a/Source/cmExtraSublimeTextGenerator.cxx
+++ b/Source/cmExtraSublimeTextGenerator.cxx
@@ -362,9 +362,8 @@ std::string cmExtraSublimeTextGenerator::ComputeFlagsForObject(
// Add source file specific flags.
if (const char* cflags = source->GetProperty("COMPILE_FLAGS")) {
- cmGeneratorExpression ge;
- const char* processed = ge.Parse(cflags)->Evaluate(lg, config);
- lg->AppendFlags(flags, processed);
+ cmGeneratorExpressionInterpreter genexInterpreter(lg, gtgt, config);
+ lg->AppendFlags(flags, genexInterpreter.Evaluate(cflags));
}
return flags;
@@ -380,6 +379,7 @@ std::string cmExtraSublimeTextGenerator::ComputeDefines(
cmMakefile* makefile = lg->GetMakefile();
const std::string& language = source->GetLanguage();
const std::string& config = makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
+ cmGeneratorExpressionInterpreter genexInterpreter(lg, target, config);
// Add the export symbol definition for shared library objects.
if (const char* exportMacro = target->GetExportMacro()) {
@@ -388,11 +388,14 @@ std::string cmExtraSublimeTextGenerator::ComputeDefines(
// Add preprocessor definitions for this target and configuration.
lg->AddCompileDefinitions(defines, target, config, language);
- lg->AppendDefines(defines, source->GetProperty("COMPILE_DEFINITIONS"));
- {
- std::string defPropName = "COMPILE_DEFINITIONS_";
- defPropName += cmSystemTools::UpperCase(config);
- lg->AppendDefines(defines, source->GetProperty(defPropName));
+ if (const char* compile_defs = source->GetProperty("COMPILE_DEFINITIONS")) {
+ lg->AppendDefines(defines, genexInterpreter.Evaluate(compile_defs));
+ }
+
+ std::string defPropName = "COMPILE_DEFINITIONS_";
+ defPropName += cmSystemTools::UpperCase(config);
+ if (const char* config_compile_defs = source->GetProperty(defPropName)) {
+ lg->AppendDefines(defines, genexInterpreter.Evaluate(config_compile_defs));
}
std::string definesString;
diff --git a/Source/cmGeneratorExpression.h b/Source/cmGeneratorExpression.h
index cface0d..611fbf8 100644
--- a/Source/cmGeneratorExpression.h
+++ b/Source/cmGeneratorExpression.h
@@ -153,4 +153,54 @@ private:
bool EvaluateForBuildsystem;
};
+class cmGeneratorExpressionInterpreter
+{
+ CM_DISABLE_COPY(cmGeneratorExpressionInterpreter)
+
+public:
+ cmGeneratorExpressionInterpreter(cmLocalGenerator* localGenerator,
+ cmGeneratorTarget* generatorTarget,
+ const std::string& config)
+ : LocalGenerator(localGenerator)
+ , GeneratorTarget(generatorTarget)
+ , Config(config)
+ {
+ }
+
+ const char* Evaluate(const char* expression)
+ {
+ this->CompiledGeneratorExpression =
+ this->GeneratorExpression.Parse(expression);
+
+ return this->CompiledGeneratorExpression->Evaluate(
+ this->LocalGenerator, this->Config, false, this->GeneratorTarget);
+ }
+ const char* Evaluate(const std::string& expression)
+ {
+ return this->Evaluate(expression.c_str());
+ }
+
+protected:
+ cmGeneratorExpression& GetGeneratorExpression()
+ {
+ return this->GeneratorExpression;
+ }
+
+ cmCompiledGeneratorExpression& GetCompiledGeneratorExpression()
+ {
+ return *(this->CompiledGeneratorExpression);
+ }
+
+ cmLocalGenerator* GetLocalGenerator() { return this->LocalGenerator; }
+
+ cmGeneratorTarget* GetGeneratorTarget() { return this->GeneratorTarget; }
+
+private:
+ cmGeneratorExpression GeneratorExpression;
+ std::unique_ptr<cmCompiledGeneratorExpression> CompiledGeneratorExpression;
+ cmLocalGenerator* LocalGenerator = nullptr;
+ cmGeneratorTarget* GeneratorTarget = nullptr;
+ std::string Config;
+};
+
#endif
diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h
index 99f33e5..92e6a29 100644
--- a/Source/cmGlobalGenerator.h
+++ b/Source/cmGlobalGenerator.h
@@ -358,6 +358,10 @@ public:
virtual bool IsIPOSupported() const { return false; }
+ /** Return whether the generator can import external visual studio project
+ using INCLUDE_EXTERNAL_MSPROJECT */
+ virtual bool IsIncludeExternalMSProjectSupported() const { return false; }
+
/** Return whether the generator should use EFFECTIVE_PLATFORM_NAME. This is
relevant for mixed macOS and iOS builds. */
virtual bool UseEffectivePlatformName(cmMakefile*) const { return false; }
diff --git a/Source/cmGlobalVisualStudioGenerator.h b/Source/cmGlobalVisualStudioGenerator.h
index 55a6813..f4fc3cf 100644
--- a/Source/cmGlobalVisualStudioGenerator.h
+++ b/Source/cmGlobalVisualStudioGenerator.h
@@ -101,6 +101,8 @@ public:
/** Return true if building for Windows CE */
virtual bool TargetsWindowsCE() const { return false; }
+ bool IsIncludeExternalMSProjectSupported() const override { return true; }
+
class TargetSet : public std::set<cmGeneratorTarget const*>
{
};
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index c376c8d..bbf4175 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -676,9 +676,51 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateXCodeSourceFileFromPath(
return buildFile;
}
+class XCodeGeneratorExpressionInterpreter
+ : public cmGeneratorExpressionInterpreter
+{
+ CM_DISABLE_COPY(XCodeGeneratorExpressionInterpreter)
+
+public:
+ XCodeGeneratorExpressionInterpreter(cmSourceFile* sourceFile,
+ cmLocalGenerator* localGenerator,
+ cmGeneratorTarget* generatorTarget)
+ : cmGeneratorExpressionInterpreter(localGenerator, generatorTarget,
+ "NO-PER-CONFIG-SUPPORT-IN-XCODE")
+ , SourceFile(sourceFile)
+ {
+ }
+
+ using cmGeneratorExpressionInterpreter::Evaluate;
+
+ const char* Evaluate(const char* expression, const char* property)
+ {
+ const char* processed = this->Evaluate(expression);
+ if (this->GetCompiledGeneratorExpression()
+ .GetHadContextSensitiveCondition()) {
+ std::ostringstream e;
+ /* clang-format off */
+ e <<
+ "Xcode does not support per-config per-source " << property << ":\n"
+ " " << expression << "\n"
+ "specified for source:\n"
+ " " << this->SourceFile->GetFullPath() << "\n";
+ /* clang-format on */
+ this->GetLocalGenerator()->IssueMessage(cmake::FATAL_ERROR, e.str());
+ }
+
+ return processed;
+ }
+
+private:
+ cmSourceFile* SourceFile = nullptr;
+};
+
cmXCodeObject* cmGlobalXCodeGenerator::CreateXCodeSourceFile(
cmLocalGenerator* lg, cmSourceFile* sf, cmGeneratorTarget* gtgt)
{
+ XCodeGeneratorExpressionInterpreter genexInterpreter(sf, lg, gtgt);
+
// Add flags from target and source file properties.
std::string flags;
const char* srcfmt = sf->GetProperty("Fortran_FORMAT");
@@ -693,30 +735,16 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateXCodeSourceFile(
break;
}
if (const char* cflags = sf->GetProperty("COMPILE_FLAGS")) {
- cmGeneratorExpression ge;
- std::string configName = "NO-PER-CONFIG-SUPPORT-IN-XCODE";
- std::unique_ptr<cmCompiledGeneratorExpression> compiledExpr =
- ge.Parse(cflags);
- const char* processed =
- compiledExpr->Evaluate(lg, configName, false, gtgt);
- if (compiledExpr->GetHadContextSensitiveCondition()) {
- std::ostringstream e;
- /* clang-format off */
- e <<
- "Xcode does not support per-config per-source COMPILE_FLAGS:\n"
- " " << cflags << "\n"
- "specified for source:\n"
- " " << sf->GetFullPath() << "\n";
- /* clang-format on */
- lg->IssueMessage(cmake::FATAL_ERROR, e.str());
- }
- lg->AppendFlags(flags, processed);
+ lg->AppendFlags(flags, genexInterpreter.Evaluate(cflags, "COMPILE_FLAGS"));
}
// Add per-source definitions.
BuildObjectListOrString flagsBuild(this, false);
- this->AppendDefines(flagsBuild, sf->GetProperty("COMPILE_DEFINITIONS"),
- true);
+ if (const char* compile_defs = sf->GetProperty("COMPILE_DEFINITIONS")) {
+ this->AppendDefines(
+ flagsBuild,
+ genexInterpreter.Evaluate(compile_defs, "COMPILE_DEFINITIONS"), true);
+ }
if (!flagsBuild.IsEmpty()) {
if (!flags.empty()) {
flags += ' ';
diff --git a/Source/cmIncludeExternalMSProjectCommand.cxx b/Source/cmIncludeExternalMSProjectCommand.cxx
index bd16b1d..85e8cd3 100644
--- a/Source/cmIncludeExternalMSProjectCommand.cxx
+++ b/Source/cmIncludeExternalMSProjectCommand.cxx
@@ -3,6 +3,7 @@
#include "cmIncludeExternalMSProjectCommand.h"
#ifdef _WIN32
+#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
#include "cmStateTypes.h"
#include "cmSystemTools.h"
@@ -22,7 +23,9 @@ bool cmIncludeExternalMSProjectCommand::InitialPass(
}
// only compile this for win32 to avoid coverage errors
#ifdef _WIN32
- if (this->Makefile->GetDefinition("WIN32")) {
+ if (this->Makefile->GetDefinition("WIN32") ||
+ this->Makefile->GetGlobalGenerator()
+ ->IsIncludeExternalMSProjectSupported()) {
enum Doing
{
DoingNone,
diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx
index 477ce51..2d969d2 100644
--- a/Source/cmLocalNinjaGenerator.cxx
+++ b/Source/cmLocalNinjaGenerator.cxx
@@ -207,6 +207,9 @@ void cmLocalNinjaGenerator::WritePools(std::ostream& os)
const char* jobpools =
this->GetCMakeInstance()->GetState()->GetGlobalProperty("JOB_POOLS");
+ if (!jobpools) {
+ jobpools = this->GetMakefile()->GetDefinition("CMAKE_JOB_POOLS");
+ }
if (jobpools) {
cmGlobalNinjaGenerator::WriteComment(
os, "Pools defined by global property JOB_POOLS");
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
index f01ed7a..53966cd 100644
--- a/Source/cmLocalVisualStudio7Generator.cxx
+++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -615,6 +615,7 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(
switch (target->GetType()) {
case cmStateEnums::OBJECT_LIBRARY:
targetBuilds = false; // no manifest tool for object library
+ CM_FALLTHROUGH;
case cmStateEnums::STATIC_LIBRARY:
projectType = "typeStaticLibrary";
configType = "4";
@@ -630,6 +631,7 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(
case cmStateEnums::UTILITY:
case cmStateEnums::GLOBAL_TARGET:
configType = "10";
+ CM_FALLTHROUGH;
default:
targetBuilds = false;
break;
@@ -1456,15 +1458,14 @@ cmLocalVisualStudio7GeneratorFCInfo::cmLocalVisualStudio7GeneratorFCInfo(
i != configs.end(); ++i, ++ci) {
std::string configUpper = cmSystemTools::UpperCase(*i);
cmLVS7GFileConfig fc;
+ cmGeneratorExpressionInterpreter genexInterpreter(lg, gt, *i);
bool needfc = false;
if (!objectName.empty()) {
fc.ObjectName = objectName;
needfc = true;
}
if (const char* cflags = sf.GetProperty("COMPILE_FLAGS")) {
- cmGeneratorExpression ge;
- std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(cflags);
- fc.CompileFlags = cge->Evaluate(lg, *i, false, gt);
+ fc.CompileFlags = genexInterpreter.Evaluate(cflags);
needfc = true;
}
if (lg->FortranProject) {
@@ -1483,13 +1484,13 @@ cmLocalVisualStudio7GeneratorFCInfo::cmLocalVisualStudio7GeneratorFCInfo(
}
}
if (const char* cdefs = sf.GetProperty("COMPILE_DEFINITIONS")) {
- fc.CompileDefs = cdefs;
+ fc.CompileDefs = genexInterpreter.Evaluate(cdefs);
needfc = true;
}
std::string defPropName = "COMPILE_DEFINITIONS_";
defPropName += configUpper;
- if (const char* ccdefs = sf.GetProperty(defPropName.c_str())) {
- fc.CompileDefsConfig = ccdefs;
+ if (const char* ccdefs = sf.GetProperty(defPropName)) {
+ fc.CompileDefsConfig = genexInterpreter.Evaluate(ccdefs);
needfc = true;
}
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index 7db010c..5e0c582 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -425,6 +425,8 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile(
std::string config = this->LocalGenerator->GetConfigName();
std::string configUpper = cmSystemTools::UpperCase(config);
+ cmGeneratorExpressionInterpreter genexInterpreter(
+ this->LocalGenerator, this->GeneratorTarget, config);
// Add Fortran format flags.
if (lang == "Fortran") {
@@ -433,10 +435,7 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile(
// Add flags from source file properties.
if (const char* cflags = source.GetProperty("COMPILE_FLAGS")) {
- cmGeneratorExpression ge;
- std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(cflags);
- const char* evaluatedFlags = cge->Evaluate(this->LocalGenerator, config,
- false, this->GeneratorTarget);
+ const char* evaluatedFlags = genexInterpreter.Evaluate(cflags);
this->LocalGenerator->AppendFlags(flags, evaluatedFlags);
*this->FlagFileStream << "# Custom flags: " << relativeObj
<< "_FLAGS = " << evaluatedFlags << "\n"
@@ -448,18 +447,19 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile(
// Add source-sepcific preprocessor definitions.
if (const char* compile_defs = source.GetProperty("COMPILE_DEFINITIONS")) {
- this->LocalGenerator->AppendDefines(defines, compile_defs);
+ const char* evaluatedDefs = genexInterpreter.Evaluate(compile_defs);
+ this->LocalGenerator->AppendDefines(defines, evaluatedDefs);
*this->FlagFileStream << "# Custom defines: " << relativeObj
- << "_DEFINES = " << compile_defs << "\n"
+ << "_DEFINES = " << evaluatedDefs << "\n"
<< "\n";
}
std::string defPropName = "COMPILE_DEFINITIONS_";
defPropName += configUpper;
if (const char* config_compile_defs = source.GetProperty(defPropName)) {
- this->LocalGenerator->AppendDefines(defines, config_compile_defs);
+ const char* evaluatedDefs = genexInterpreter.Evaluate(config_compile_defs);
+ this->LocalGenerator->AppendDefines(defines, evaluatedDefs);
*this->FlagFileStream << "# Custom defines: " << relativeObj << "_DEFINES_"
- << configUpper << " = " << config_compile_defs
- << "\n"
+ << configUpper << " = " << evaluatedDefs << "\n"
<< "\n";
}
@@ -657,8 +657,8 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile(
}
// Maybe insert a compiler launcher like ccache or distcc
- if (!compileCommands.empty() &&
- (lang == "C" || lang == "CXX" || lang == "CUDA")) {
+ if (!compileCommands.empty() && (lang == "C" || lang == "CXX" ||
+ lang == "Fortran" || lang == "CUDA")) {
std::string const clauncher_prop = lang + "_COMPILER_LAUNCHER";
const char* clauncher =
this->GeneratorTarget->GetProperty(clauncher_prop);
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index 5805259..1036977 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -136,12 +136,11 @@ std::string cmNinjaTargetGenerator::ComputeFlagsForObject(
// Add source file specific flags.
if (const char* cflags = source->GetProperty("COMPILE_FLAGS")) {
- std::string config = this->LocalGenerator->GetConfigName();
- cmGeneratorExpression ge;
- std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(cflags);
- const char* evaluatedFlags = cge->Evaluate(this->LocalGenerator, config,
- false, this->GeneratorTarget);
- this->LocalGenerator->AppendFlags(flags, evaluatedFlags);
+ cmGeneratorExpressionInterpreter genexInterpreter(
+ this->LocalGenerator, this->GeneratorTarget,
+ this->LocalGenerator->GetConfigName());
+ this->LocalGenerator->AppendFlags(flags,
+ genexInterpreter.Evaluate(cflags));
}
return flags;
@@ -178,13 +177,20 @@ std::string cmNinjaTargetGenerator::ComputeDefines(cmSourceFile const* source,
const std::string& language)
{
std::set<std::string> defines;
- this->LocalGenerator->AppendDefines(
- defines, source->GetProperty("COMPILE_DEFINITIONS"));
- {
- std::string defPropName = "COMPILE_DEFINITIONS_";
- defPropName += cmSystemTools::UpperCase(this->GetConfigName());
- this->LocalGenerator->AppendDefines(defines,
- source->GetProperty(defPropName));
+ const std::string config = this->LocalGenerator->GetConfigName();
+ cmGeneratorExpressionInterpreter genexInterpreter(
+ this->LocalGenerator, this->GeneratorTarget, config);
+
+ if (const char* compile_defs = source->GetProperty("COMPILE_DEFINITIONS")) {
+ this->LocalGenerator->AppendDefines(
+ defines, genexInterpreter.Evaluate(compile_defs));
+ }
+
+ std::string defPropName = "COMPILE_DEFINITIONS_";
+ defPropName += cmSystemTools::UpperCase(config);
+ if (const char* config_compile_defs = source->GetProperty(defPropName)) {
+ this->LocalGenerator->AppendDefines(
+ defines, genexInterpreter.Evaluate(config_compile_defs));
}
std::string definesString = this->GetDefines(language);
@@ -647,7 +653,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
// Maybe insert a compiler launcher like ccache or distcc
if (!compileCmds.empty() &&
- (lang == "C" || lang == "CXX" || lang == "CUDA")) {
+ (lang == "C" || lang == "CXX" || lang == "Fortran" || lang == "CUDA")) {
std::string const clauncher_prop = lang + "_COMPILER_LAUNCHER";
const char* clauncher = this->GeneratorTarget->GetProperty(clauncher_prop);
if (clauncher && *clauncher) {
diff --git a/Source/cmPipeConnection.cxx b/Source/cmPipeConnection.cxx
index 9e565f6..3dab2f0 100644
--- a/Source/cmPipeConnection.cxx
+++ b/Source/cmPipeConnection.cxx
@@ -2,6 +2,8 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmPipeConnection.h"
+#include <algorithm>
+
#include "cmServer.h"
cmPipeConnection::cmPipeConnection(const std::string& name,
@@ -13,39 +15,33 @@ cmPipeConnection::cmPipeConnection(const std::string& name,
void cmPipeConnection::Connect(uv_stream_t* server)
{
- if (this->ClientPipe) {
+ if (this->WriteStream.get()) {
// Accept and close all pipes but the first:
- uv_pipe_t* rejectPipe = new uv_pipe_t();
+ cm::uv_pipe_ptr rejectPipe;
+
+ rejectPipe.init(*this->Server->GetLoop(), 0);
+ uv_accept(server, rejectPipe);
- uv_pipe_init(this->Server->GetLoop(), rejectPipe, 0);
- uv_accept(server, reinterpret_cast<uv_stream_t*>(rejectPipe));
- uv_close(reinterpret_cast<uv_handle_t*>(rejectPipe),
- &on_close_delete<uv_pipe_t>);
return;
}
- this->ClientPipe = new uv_pipe_t();
- uv_pipe_init(this->Server->GetLoop(), this->ClientPipe, 0);
- this->ClientPipe->data = static_cast<cmEventBasedConnection*>(this);
- auto client = reinterpret_cast<uv_stream_t*>(this->ClientPipe);
- if (uv_accept(server, client) != 0) {
- uv_close(reinterpret_cast<uv_handle_t*>(client),
- &on_close_delete<uv_pipe_t>);
- this->ClientPipe = nullptr;
+ cm::uv_pipe_ptr ClientPipe;
+ ClientPipe.init(*this->Server->GetLoop(), 0,
+ static_cast<cmEventBasedConnection*>(this));
+
+ if (uv_accept(server, ClientPipe) != 0) {
return;
}
- this->ReadStream = client;
- this->WriteStream = client;
- uv_read_start(this->ReadStream, on_alloc_buffer, on_read);
+ uv_read_start(ClientPipe, on_alloc_buffer, on_read);
+ WriteStream = std::move(ClientPipe);
Server->OnConnected(this);
}
bool cmPipeConnection::OnServeStart(std::string* errorMessage)
{
- this->ServerPipe = new uv_pipe_t();
- uv_pipe_init(this->Server->GetLoop(), this->ServerPipe, 0);
- this->ServerPipe->data = static_cast<cmEventBasedConnection*>(this);
+ this->ServerPipe.init(*this->Server->GetLoop(), 0,
+ static_cast<cmEventBasedConnection*>(this));
int r;
if ((r = uv_pipe_bind(this->ServerPipe, this->PipeName.c_str())) != 0) {
@@ -53,8 +49,8 @@ bool cmPipeConnection::OnServeStart(std::string* errorMessage)
": " + uv_err_name(r);
return false;
}
- auto serverStream = reinterpret_cast<uv_stream_t*>(this->ServerPipe);
- if ((r = uv_listen(serverStream, 1, on_new_connection)) != 0) {
+
+ if ((r = uv_listen(this->ServerPipe, 1, on_new_connection)) != 0) {
*errorMessage = std::string("Internal Error listening on ") +
this->PipeName + ": " + uv_err_name(r);
return false;
@@ -65,18 +61,11 @@ bool cmPipeConnection::OnServeStart(std::string* errorMessage)
bool cmPipeConnection::OnConnectionShuttingDown()
{
- if (this->ClientPipe) {
- uv_close(reinterpret_cast<uv_handle_t*>(this->ClientPipe),
- &on_close_delete<uv_pipe_t>);
+ if (this->WriteStream.get()) {
this->WriteStream->data = nullptr;
}
- uv_close(reinterpret_cast<uv_handle_t*>(this->ServerPipe),
- &on_close_delete<uv_pipe_t>);
- this->ClientPipe = nullptr;
- this->ServerPipe = nullptr;
- this->WriteStream = nullptr;
- this->ReadStream = nullptr;
+ this->ServerPipe.reset();
return cmEventBasedConnection::OnConnectionShuttingDown();
}
diff --git a/Source/cmPipeConnection.h b/Source/cmPipeConnection.h
index 7b89842..49f9fdf 100644
--- a/Source/cmPipeConnection.h
+++ b/Source/cmPipeConnection.h
@@ -4,6 +4,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
+#include "cmUVHandlePtr.h"
#include <string>
#include "cmConnection.h"
@@ -23,6 +24,5 @@ public:
private:
const std::string PipeName;
- uv_pipe_t* ServerPipe = nullptr;
- uv_pipe_t* ClientPipe = nullptr;
+ cm::uv_pipe_ptr ServerPipe;
};
diff --git a/Source/cmQtAutoGeneratorInitializer.cxx b/Source/cmQtAutoGeneratorInitializer.cxx
index bd692a2..14743de 100644
--- a/Source/cmQtAutoGeneratorInitializer.cxx
+++ b/Source/cmQtAutoGeneratorInitializer.cxx
@@ -821,40 +821,39 @@ void cmQtAutoGeneratorInitializer::InitCustomTargets()
this->Target->Target->AddPreBuildCommand(cc);
} else {
- // Convert file dependencies std::set to std::vector
- std::vector<std::string> autogenDepends(autogenDependFiles.begin(),
- autogenDependFiles.end());
-
// Add link library target dependencies to the autogen target
// dependencies
- for (std::string const& config : this->ConfigsList) {
- cmLinkImplementationLibraries const* libs =
- this->Target->GetLinkImplementationLibraries(config);
- if (libs != nullptr) {
- for (cmLinkItem const& item : libs->Libraries) {
- cmGeneratorTarget const* libTarget = item.Target;
- if ((libTarget != nullptr) &&
- !StaticLibraryCycle(this->Target, libTarget, config)) {
- std::string util;
- if (this->ConfigsList.size() > 1) {
- util += "$<$<CONFIG:";
- util += config;
- util += ">:";
- }
- util += libTarget->GetName();
- if (this->ConfigsList.size() > 1) {
- util += ">";
+ {
+ // add_dependencies/addUtility do not support generator expressions.
+ // We depend only on the libraries found in all configs therefore.
+ std::map<cmGeneratorTarget const*, std::size_t> commonTargets;
+ for (std::string const& config : this->ConfigsList) {
+ cmLinkImplementationLibraries const* libs =
+ this->Target->GetLinkImplementationLibraries(config);
+ if (libs != nullptr) {
+ for (cmLinkItem const& item : libs->Libraries) {
+ cmGeneratorTarget const* libTarget = item.Target;
+ if ((libTarget != nullptr) &&
+ !StaticLibraryCycle(this->Target, libTarget, config)) {
+ // Increment target config count
+ commonTargets[libTarget]++;
}
- autogenDepends.push_back(util);
}
}
}
+ for (auto const& item : commonTargets) {
+ if (item.second == this->ConfigsList.size()) {
+ autogenDependTargets.insert(item.first->Target);
+ }
+ }
}
// Create autogen target
cmTarget* autogenTarget = makefile->AddUtilityCommand(
this->AutogenTargetName, cmMakefile::TargetOrigin::Generator, true,
- this->DirWork.c_str(), /*byproducts=*/autogenProvides, autogenDepends,
+ this->DirWork.c_str(), /*byproducts=*/autogenProvides,
+ std::vector<std::string>(autogenDependFiles.begin(),
+ autogenDependFiles.end()),
commandLines, false, autogenComment.c_str());
// Create autogen generator target
localGen->AddGeneratorTarget(
diff --git a/Source/cmServer.cxx b/Source/cmServer.cxx
index 9af4c0a..1b04ca2 100644
--- a/Source/cmServer.cxx
+++ b/Source/cmServer.cxx
@@ -18,17 +18,19 @@
#include <cstdint>
#include <iostream>
#include <memory>
+#include <mutex>
#include <utility>
void on_signal(uv_signal_t* signal, int signum)
{
- auto conn = reinterpret_cast<cmServerBase*>(signal->data);
+ auto conn = static_cast<cmServerBase*>(signal->data);
conn->OnSignal(signum);
}
static void on_walk_to_shutdown(uv_handle_t* handle, void* arg)
{
(void)arg;
+ assert(uv_is_closing(handle));
if (!uv_is_closing(handle)) {
uv_close(handle, &cmEventBasedConnection::on_close);
}
@@ -58,6 +60,8 @@ cmServer::cmServer(cmConnection* conn, bool supportExperimental)
cmServer::~cmServer()
{
+ Close();
+
for (cmServerProtocol* p : this->SupportedProtocols) {
delete p;
}
@@ -409,7 +413,7 @@ void cmServer::StartShutDown()
static void __start_thread(void* arg)
{
- auto server = reinterpret_cast<cmServerBase*>(arg);
+ auto server = static_cast<cmServerBase*>(arg);
std::string error;
bool success = server->Serve(&error);
if (!success || error.empty() == false) {
@@ -417,22 +421,19 @@ static void __start_thread(void* arg)
}
}
-static void __shutdownThread(uv_async_t* arg)
-{
- auto server = reinterpret_cast<cmServerBase*>(arg->data);
- on_walk_to_shutdown(reinterpret_cast<uv_handle_t*>(arg), nullptr);
- server->StartShutDown();
-}
-
bool cmServerBase::StartServeThread()
{
ServeThreadRunning = true;
- uv_async_init(&Loop, &this->ShutdownSignal, __shutdownThread);
- this->ShutdownSignal.data = this;
uv_thread_create(&ServeThread, __start_thread, this);
return true;
}
+static void __shutdownThread(uv_async_t* arg)
+{
+ auto server = static_cast<cmServerBase*>(arg->data);
+ server->StartShutDown();
+}
+
bool cmServerBase::Serve(std::string* errorMessage)
{
#ifndef NDEBUG
@@ -443,14 +444,13 @@ bool cmServerBase::Serve(std::string* errorMessage)
errorMessage->clear();
- uv_signal_init(&Loop, &this->SIGINTHandler);
- uv_signal_init(&Loop, &this->SIGHUPHandler);
+ ShutdownSignal.init(Loop, __shutdownThread, this);
- this->SIGINTHandler.data = this;
- this->SIGHUPHandler.data = this;
+ SIGINTHandler.init(Loop, this);
+ SIGHUPHandler.init(Loop, this);
- uv_signal_start(&this->SIGINTHandler, &on_signal, SIGINT);
- uv_signal_start(&this->SIGHUPHandler, &on_signal, SIGHUP);
+ SIGINTHandler.start(&on_signal, SIGINT);
+ SIGHUPHandler.start(&on_signal, SIGHUP);
OnServeStart();
@@ -473,7 +473,6 @@ bool cmServerBase::Serve(std::string* errorMessage)
return false;
}
- ServeThreadRunning = false;
return true;
}
@@ -487,18 +486,12 @@ void cmServerBase::OnServeStart()
void cmServerBase::StartShutDown()
{
- if (!uv_is_closing(
- reinterpret_cast<const uv_handle_t*>(&this->SIGINTHandler))) {
- uv_signal_stop(&this->SIGINTHandler);
- }
-
- if (!uv_is_closing(
- reinterpret_cast<const uv_handle_t*>(&this->SIGHUPHandler))) {
- uv_signal_stop(&this->SIGHUPHandler);
- }
+ ShutdownSignal.reset();
+ SIGINTHandler.reset();
+ SIGHUPHandler.reset();
{
- cm::unique_lock<cm::shared_mutex> lock(ConnectionsMutex);
+ std::unique_lock<cm::shared_mutex> lock(ConnectionsMutex);
for (auto& connection : Connections) {
connection->OnConnectionShuttingDown();
}
@@ -519,26 +512,33 @@ cmServerBase::cmServerBase(cmConnection* connection)
{
auto err = uv_loop_init(&Loop);
(void)err;
+ Loop.data = this;
assert(err == 0);
AddNewConnection(connection);
}
-cmServerBase::~cmServerBase()
+void cmServerBase::Close()
{
+ if (Loop.data) {
+ if (ServeThreadRunning) {
+ this->ShutdownSignal.send();
+ uv_thread_join(&ServeThread);
+ }
- if (ServeThreadRunning) {
- uv_async_send(&this->ShutdownSignal);
- uv_thread_join(&ServeThread);
+ uv_loop_close(&Loop);
+ Loop.data = nullptr;
}
-
- uv_loop_close(&Loop);
+}
+cmServerBase::~cmServerBase()
+{
+ Close();
}
void cmServerBase::AddNewConnection(cmConnection* ownedConnection)
{
{
- cm::unique_lock<cm::shared_mutex> lock(ConnectionsMutex);
+ std::unique_lock<cm::shared_mutex> lock(ConnectionsMutex);
Connections.emplace_back(ownedConnection);
}
ownedConnection->SetServer(this);
@@ -555,13 +555,13 @@ void cmServerBase::OnDisconnect(cmConnection* pConnection)
return m.get() == pConnection;
};
{
- cm::unique_lock<cm::shared_mutex> lock(ConnectionsMutex);
+ std::unique_lock<cm::shared_mutex> lock(ConnectionsMutex);
Connections.erase(
std::remove_if(Connections.begin(), Connections.end(), pred),
Connections.end());
}
if (Connections.empty()) {
- StartShutDown();
+ this->ShutdownSignal.send();
}
}
diff --git a/Source/cmServer.h b/Source/cmServer.h
index 6e46f8c..ca37ce2 100644
--- a/Source/cmServer.h
+++ b/Source/cmServer.h
@@ -8,6 +8,8 @@
#include "cm_thread.hxx"
#include "cm_uv.h"
+#include "cmUVHandlePtr.h"
+
#include <memory> // IWYU pragma: keep
#include <string>
#include <vector>
@@ -58,7 +60,7 @@ public:
virtual bool OnSignal(int signum);
uv_loop_t* GetLoop();
-
+ void Close();
void OnDisconnect(cmConnection* pConnection);
protected:
@@ -67,7 +69,7 @@ protected:
bool ServeThreadRunning = false;
uv_thread_t ServeThread;
- uv_async_t ShutdownSignal;
+ cm::uv_async_ptr ShutdownSignal;
#ifndef NDEBUG
public:
// When the server starts it will mark down it's current thread ID,
@@ -80,8 +82,8 @@ protected:
uv_loop_t Loop;
- uv_signal_t SIGINTHandler;
- uv_signal_t SIGHUPHandler;
+ cm::uv_signal_ptr SIGINTHandler;
+ cm::uv_signal_ptr SIGHUPHandler;
};
class cmServer : public cmServerBase
diff --git a/Source/cmServerConnection.cxx b/Source/cmServerConnection.cxx
index 44af75f..78c8f06 100644
--- a/Source/cmServerConnection.cxx
+++ b/Source/cmServerConnection.cxx
@@ -5,6 +5,9 @@
#include "cmConfigure.h"
#include "cmServer.h"
#include "cmServerDictionary.h"
+#include "cm_uv.h"
+
+#include <algorithm>
#ifdef _WIN32
#include "io.h"
#else
@@ -18,36 +21,34 @@ cmStdIoConnection::cmStdIoConnection(
{
}
-void cmStdIoConnection::SetupStream(uv_stream_t*& stream, int file_id)
+cm::uv_stream_ptr cmStdIoConnection::SetupStream(int file_id)
{
- assert(stream == nullptr);
switch (uv_guess_handle(file_id)) {
case UV_TTY: {
- auto tty = new uv_tty_t();
- uv_tty_init(this->Server->GetLoop(), tty, file_id, file_id == 0);
+ cm::uv_tty_ptr tty;
+ tty.init(*this->Server->GetLoop(), file_id, file_id == 0,
+ static_cast<cmEventBasedConnection*>(this));
uv_tty_set_mode(tty, UV_TTY_MODE_NORMAL);
- stream = reinterpret_cast<uv_stream_t*>(tty);
- break;
+ return std::move(tty);
}
case UV_FILE:
if (file_id == 0) {
- return;
+ return nullptr;
}
// Intentional fallthrough; stdin can _not_ be treated as a named
// pipe, however stdout can be.
CM_FALLTHROUGH;
case UV_NAMED_PIPE: {
- auto pipe = new uv_pipe_t();
- uv_pipe_init(this->Server->GetLoop(), pipe, 0);
+ cm::uv_pipe_ptr pipe;
+ pipe.init(*this->Server->GetLoop(), 0,
+ static_cast<cmEventBasedConnection*>(this));
uv_pipe_open(pipe, file_id);
- stream = reinterpret_cast<uv_stream_t*>(pipe);
- break;
+ return std::move(pipe);
}
default:
assert(false && "Unable to determine stream type");
- return;
+ return nullptr;
}
- stream->data = static_cast<cmEventBasedConnection*>(this);
}
void cmStdIoConnection::SetServer(cmServerBase* s)
@@ -57,14 +58,14 @@ void cmStdIoConnection::SetServer(cmServerBase* s)
return;
}
- SetupStream(this->ReadStream, 0);
- SetupStream(this->WriteStream, 1);
+ this->ReadStream = SetupStream(0);
+ this->WriteStream = SetupStream(1);
}
void shutdown_connection(uv_prepare_t* prepare)
{
cmStdIoConnection* connection =
- reinterpret_cast<cmStdIoConnection*>(prepare->data);
+ static_cast<cmStdIoConnection*>(prepare->data);
if (!uv_is_closing(reinterpret_cast<uv_handle_t*>(prepare))) {
uv_close(reinterpret_cast<uv_handle_t*>(prepare),
@@ -76,7 +77,7 @@ void shutdown_connection(uv_prepare_t* prepare)
bool cmStdIoConnection::OnServeStart(std::string* pString)
{
Server->OnConnected(this);
- if (this->ReadStream) {
+ if (this->ReadStream.get()) {
uv_read_start(this->ReadStream, on_alloc_buffer, on_read);
} else if (uv_guess_handle(0) == UV_FILE) {
char buffer[1024];
@@ -94,44 +95,14 @@ bool cmStdIoConnection::OnServeStart(std::string* pString)
return cmConnection::OnServeStart(pString);
}
-void cmStdIoConnection::ShutdownStream(uv_stream_t*& stream)
-{
- if (!stream) {
- return;
- }
- switch (stream->type) {
- case UV_TTY: {
- assert(!uv_is_closing(reinterpret_cast<uv_handle_t*>(stream)));
- if (!uv_is_closing(reinterpret_cast<uv_handle_t*>(stream))) {
- uv_close(reinterpret_cast<uv_handle_t*>(stream),
- &on_close_delete<uv_tty_t>);
- }
- break;
- }
- case UV_FILE:
- case UV_NAMED_PIPE: {
- assert(!uv_is_closing(reinterpret_cast<uv_handle_t*>(stream)));
- if (!uv_is_closing(reinterpret_cast<uv_handle_t*>(stream))) {
- uv_close(reinterpret_cast<uv_handle_t*>(stream),
- &on_close_delete<uv_pipe_t>);
- }
- break;
- }
- default:
- assert(false && "Unable to determine stream type");
- }
-
- stream = nullptr;
-}
-
bool cmStdIoConnection::OnConnectionShuttingDown()
{
- if (ReadStream) {
+ if (ReadStream.get()) {
uv_read_stop(ReadStream);
+ ReadStream->data = nullptr;
}
- ShutdownStream(ReadStream);
- ShutdownStream(WriteStream);
+ this->ReadStream.reset();
cmEventBasedConnection::OnConnectionShuttingDown();
diff --git a/Source/cmServerConnection.h b/Source/cmServerConnection.h
index 4ca908d..a70edb4 100644
--- a/Source/cmServerConnection.h
+++ b/Source/cmServerConnection.h
@@ -8,7 +8,7 @@
#include "cmConnection.h"
#include "cmPipeConnection.h"
-#include "cm_uv.h"
+#include "cmUVHandlePtr.h"
class cmServerBase;
@@ -46,8 +46,8 @@ public:
bool OnServeStart(std::string* pString) override;
private:
- void SetupStream(uv_stream_t*& stream, int file_id);
- void ShutdownStream(uv_stream_t*& stream);
+ cm::uv_stream_ptr SetupStream(int file_id);
+ cm::uv_stream_ptr ReadStream;
};
/***
diff --git a/Source/cmServerDictionary.h b/Source/cmServerDictionary.h
index 62dee11..685542c 100644
--- a/Source/cmServerDictionary.h
+++ b/Source/cmServerDictionary.h
@@ -97,11 +97,6 @@ static const std::string kCTEST_INFO = "ctestInfo";
static const std::string kMINIMUM_CMAKE_VERSION = "minimumCMakeVersion";
static const std::string kIS_GENERATOR_PROVIDED_KEY = "isGeneratorProvided";
-static const std::string kTARGET_CROSS_REFERENCES_KEY = "crossReferences";
-static const std::string kLINE_NUMBER_KEY = "line";
-static const std::string kBACKTRACE_KEY = "backtrace";
-static const std::string kRELATED_STATEMENTS_KEY = "relatedStatements";
-
static const std::string kSTART_MAGIC = "[== \"CMake Server\" ==[";
static const std::string kEND_MAGIC = "]== \"CMake Server\" ==]";
diff --git a/Source/cmServerProtocol.cxx b/Source/cmServerProtocol.cxx
index cfac513..ad66467 100644
--- a/Source/cmServerProtocol.cxx
+++ b/Source/cmServerProtocol.cxx
@@ -11,7 +11,6 @@
#include "cmInstallGenerator.h"
#include "cmInstallTargetGenerator.h"
#include "cmLinkLineComputer.h"
-#include "cmListFileCache.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmProperty.h"
@@ -692,6 +691,8 @@ static Json::Value DumpSourceFilesList(
std::vector<cmSourceFile*> files;
target->GetSourceFiles(files, config);
+ cmGeneratorExpressionInterpreter genexInterpreter(
+ target->GetLocalGenerator(), target, config);
std::unordered_map<LanguageData, std::vector<std::string>> fileGroups;
for (cmSourceFile* file : files) {
@@ -703,21 +704,23 @@ static Json::Value DumpSourceFilesList(
std::string compileFlags = ld.Flags;
if (const char* cflags = file->GetProperty("COMPILE_FLAGS")) {
- cmGeneratorExpression ge;
- auto cge = ge.Parse(cflags);
- const char* processed =
- cge->Evaluate(target->GetLocalGenerator(), config);
- lg->AppendFlags(compileFlags, processed);
+ lg->AppendFlags(compileFlags, genexInterpreter.Evaluate(cflags));
}
fileData.Flags = compileFlags;
fileData.IncludePathList = ld.IncludePathList;
std::set<std::string> defines;
- lg->AppendDefines(defines, file->GetProperty("COMPILE_DEFINITIONS"));
+ if (const char* defs = file->GetProperty("COMPILE_DEFINITIONS")) {
+ lg->AppendDefines(defines, genexInterpreter.Evaluate(defs));
+ }
+
const std::string defPropName =
"COMPILE_DEFINITIONS_" + cmSystemTools::UpperCase(config);
- lg->AppendDefines(defines, file->GetProperty(defPropName));
+ if (const char* config_defs = file->GetProperty(defPropName)) {
+ lg->AppendDefines(defines, genexInterpreter.Evaluate(config_defs));
+ }
+
defines.insert(ld.Defines.begin(), ld.Defines.end());
fileData.SetDefines(defines);
@@ -740,37 +743,6 @@ static Json::Value DumpSourceFilesList(
return result;
}
-static Json::Value DumpBacktrace(const cmListFileBacktrace& backtrace)
-{
- Json::Value result = Json::arrayValue;
-
- cmListFileBacktrace backtraceCopy = backtrace;
- while (!backtraceCopy.Top().FilePath.empty()) {
- Json::Value entry = Json::objectValue;
- entry[kPATH_KEY] = backtraceCopy.Top().FilePath;
- if (backtraceCopy.Top().Line) {
- entry[kLINE_NUMBER_KEY] = static_cast<int>(backtraceCopy.Top().Line);
- }
- if (!backtraceCopy.Top().Name.empty()) {
- entry[kNAME_KEY] = backtraceCopy.Top().Name;
- }
- result.append(entry);
- backtraceCopy = backtraceCopy.Pop();
- }
- return result;
-}
-
-static void DumpBacktraceRange(Json::Value& result, const std::string& type,
- cmBacktraceRange range)
-{
- for (auto const& bt : range) {
- Json::Value obj = Json::objectValue;
- obj[kTYPE_KEY] = type;
- obj[kBACKTRACE_KEY] = DumpBacktrace(bt);
- result.append(obj);
- }
-}
-
static Json::Value DumpCTestInfo(cmTest* testInfo)
{
Json::Value result = Json::objectValue;
@@ -795,9 +767,6 @@ static Json::Value DumpCTestInfo(cmTest* testInfo)
}
result[kPROPERTIES_KEY] = properties;
- // Need backtrace to figure out where this test was originally added
- result[kBACKTRACE_KEY] = DumpBacktrace(testInfo->GetBacktrace());
-
return result;
}
@@ -929,22 +898,6 @@ static Json::Value DumpTarget(cmGeneratorTarget* target,
result[kINSTALL_PATHS] = installPaths;
}
- Json::Value crossRefs = Json::objectValue;
- crossRefs[kBACKTRACE_KEY] = DumpBacktrace(target->Target->GetBacktrace());
-
- Json::Value statements = Json::arrayValue;
- DumpBacktraceRange(statements, "target_compile_definitions",
- target->Target->GetCompileDefinitionsBacktraces());
- DumpBacktraceRange(statements, "target_include_directories",
- target->Target->GetIncludeDirectoriesBacktraces());
- DumpBacktraceRange(statements, "target_compile_options",
- target->Target->GetCompileOptionsBacktraces());
- DumpBacktraceRange(statements, "target_link_libraries",
- target->Target->GetLinkImplementationBacktraces());
-
- crossRefs[kRELATED_STATEMENTS_KEY] = std::move(statements);
- result[kTARGET_CROSS_REFERENCES_KEY] = std::move(crossRefs);
-
if (target->HaveWellDefinedOutputFiles()) {
Json::Value artifacts = Json::arrayValue;
artifacts.append(
diff --git a/Source/cmStandardLexer.h b/Source/cmStandardLexer.h
index c9f42e4..b212c7e 100644
--- a/Source/cmStandardLexer.h
+++ b/Source/cmStandardLexer.h
@@ -3,7 +3,7 @@
#ifndef cmStandardLexer_h
#define cmStandardLexer_h
-#include "cmConfigure.h" // IWYU pragma: keep
+#include "cmsys/Configure.h" // IWYU pragma: keep
/* Disable some warnings. */
#if defined(_MSC_VER)
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 693f35f..de23b08 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -239,6 +239,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
this->SetPropertyDefault("COMPILE_PDB_OUTPUT_DIRECTORY", nullptr);
this->SetPropertyDefault("Fortran_FORMAT", nullptr);
this->SetPropertyDefault("Fortran_MODULE_DIRECTORY", nullptr);
+ this->SetPropertyDefault("Fortran_COMPILER_LAUNCHER", nullptr);
this->SetPropertyDefault("GNUtoMS", nullptr);
this->SetPropertyDefault("OSX_ARCHITECTURES", nullptr);
this->SetPropertyDefault("IOS_INSTALL_COMBINED", nullptr);
diff --git a/Source/cmTargetLinkLibrariesCommand.cxx b/Source/cmTargetLinkLibrariesCommand.cxx
index 37bcb70..97bb0a2 100644
--- a/Source/cmTargetLinkLibrariesCommand.cxx
+++ b/Source/cmTargetLinkLibrariesCommand.cxx
@@ -25,16 +25,17 @@ const char* cmTargetLinkLibrariesCommand::LinkLibraryTypeNames[3] = {
bool cmTargetLinkLibrariesCommand::InitialPass(
std::vector<std::string> const& args, cmExecutionStatus&)
{
- // must have one argument
+ // Must have at least one argument.
if (args.empty()) {
this->SetError("called with incorrect number of arguments");
return false;
}
-
+ // Alias targets cannot be on the LHS of this command.
if (this->Makefile->IsAlias(args[0])) {
this->SetError("can not be used on an ALIAS target.");
return false;
}
+
// Lookup the target for which libraries are specified.
this->Target =
this->Makefile->GetCMakeInstance()->GetGlobalGenerator()->FindTarget(
@@ -78,8 +79,7 @@ bool cmTargetLinkLibrariesCommand::InitialPass(
break;
}
}
-
- // now actually print the message
+ // Now actually print the message.
switch (t) {
case cmake::AUTHOR_WARNING:
this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, e.str());
@@ -94,6 +94,7 @@ bool cmTargetLinkLibrariesCommand::InitialPass(
return true;
}
+ // OBJECT libraries are not allowed on the LHS of the command.
if (this->Target->GetType() == cmStateEnums::OBJECT_LIBRARY) {
std::ostringstream e;
e << "Object library target \"" << args[0] << "\" "
@@ -103,6 +104,7 @@ bool cmTargetLinkLibrariesCommand::InitialPass(
return true;
}
+ // Having a UTILITY library on the LHS is a bug.
if (this->Target->GetType() == cmStateEnums::UTILITY) {
std::ostringstream e;
const char* modal = nullptr;
@@ -129,7 +131,7 @@ bool cmTargetLinkLibrariesCommand::InitialPass(
}
}
- // but we might not have any libs after variable expansion
+ // But we might not have any libs after variable expansion.
if (args.size() < 2) {
return true;
}
@@ -142,8 +144,8 @@ bool cmTargetLinkLibrariesCommand::InitialPass(
// specification if the keyword is encountered as the first argument.
this->CurrentProcessingState = ProcessingLinkLibraries;
- // add libraries, note that there is an optional prefix
- // of debug and optimized that can be used
+ // Add libraries, note that there is an optional prefix
+ // of debug and optimized that can be used.
for (unsigned int i = 1; i < args.size(); ++i) {
if (args[i] == "LINK_INTERFACE_LIBRARIES") {
this->CurrentProcessingState = ProcessingPlainLinkInterface;
@@ -160,8 +162,9 @@ bool cmTargetLinkLibrariesCommand::InitialPass(
this->CurrentProcessingState != ProcessingKeywordPublicInterface &&
this->CurrentProcessingState != ProcessingKeywordLinkInterface) {
this->Makefile->IssueMessage(
- cmake::FATAL_ERROR, "The INTERFACE option must appear as the second "
- "argument, just after the target name.");
+ cmake::FATAL_ERROR,
+ "The INTERFACE, PUBLIC or PRIVATE option must appear as the second "
+ "argument, just after the target name.");
return true;
}
this->CurrentProcessingState = ProcessingKeywordLinkInterface;
@@ -183,7 +186,7 @@ bool cmTargetLinkLibrariesCommand::InitialPass(
this->CurrentProcessingState != ProcessingKeywordLinkInterface) {
this->Makefile->IssueMessage(
cmake::FATAL_ERROR,
- "The PUBLIC or PRIVATE option must appear as the second "
+ "The INTERFACE, PUBLIC or PRIVATE option must appear as the second "
"argument, just after the target name.");
return true;
}
@@ -206,7 +209,7 @@ bool cmTargetLinkLibrariesCommand::InitialPass(
this->CurrentProcessingState != ProcessingKeywordLinkInterface) {
this->Makefile->IssueMessage(
cmake::FATAL_ERROR,
- "The PUBLIC or PRIVATE option must appear as the second "
+ "The INTERFACE, PUBLIC or PRIVATE option must appear as the second "
"argument, just after the target name.");
return true;
}
@@ -349,12 +352,11 @@ bool cmTargetLinkLibrariesCommand::HandleLibrary(const std::string& lib,
// form must be the plain form.
const char* existingSig =
(sig == cmTarget::KeywordTLLSignature ? "plain" : "keyword");
- e << "The " << existingSig << " signature for target_link_libraries "
- "has already been used with the target \""
- << this->Target->GetName() << "\". All uses of "
- "target_link_libraries with a target "
- << modal << " be either "
- "all-keyword or all-plain.\n";
+ e << "The " << existingSig << " signature for target_link_libraries has "
+ "already been used with the target \""
+ << this->Target->GetName()
+ << "\". All uses of target_link_libraries with a target " << modal
+ << " be either all-keyword or all-plain.\n";
this->Target->GetTllSignatureTraces(e,
sig == cmTarget::KeywordTLLSignature
? cmTarget::PlainTLLSignature
@@ -366,10 +368,13 @@ bool cmTargetLinkLibrariesCommand::HandleLibrary(const std::string& lib,
}
}
- // Handle normal case first.
+ // Handle normal case where the command was called with another keyword than
+ // INTERFACE / LINK_INTERFACE_LIBRARIES or none at all. (The "LINK_LIBRARIES"
+ // property of the target on the LHS shall be populated.)
if (this->CurrentProcessingState != ProcessingKeywordLinkInterface &&
this->CurrentProcessingState != ProcessingPlainLinkInterface) {
+ // Assure that the target on the LHS was created in the current directory.
cmTarget* t =
this->Makefile->FindLocalNonAliasTarget(this->Target->GetName());
if (!t) {
@@ -388,92 +393,100 @@ bool cmTargetLinkLibrariesCommand::HandleLibrary(const std::string& lib,
<< this->Target->GetName()
<< "\" which is not built in this directory.";
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
- } else {
-
- cmTarget* tgt = this->Makefile->GetGlobalGenerator()->FindTarget(lib);
+ return false;
+ }
- if (tgt && (tgt->GetType() != cmStateEnums::STATIC_LIBRARY) &&
- (tgt->GetType() != cmStateEnums::SHARED_LIBRARY) &&
- (tgt->GetType() != cmStateEnums::UNKNOWN_LIBRARY) &&
- (tgt->GetType() != cmStateEnums::INTERFACE_LIBRARY) &&
- !tgt->IsExecutableWithExports()) {
- std::ostringstream e;
- e << "Target \"" << lib << "\" of type "
- << cmState::GetTargetTypeName(tgt->GetType())
- << " may not be linked into another target. "
- << "One may link only to STATIC or SHARED libraries, or "
- << "to executables with the ENABLE_EXPORTS property set.";
- this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
- }
+ cmTarget* tgt = this->Makefile->GetGlobalGenerator()->FindTarget(lib);
- this->Target->AddLinkLibrary(*this->Makefile, lib, llt);
+ if (tgt && (tgt->GetType() != cmStateEnums::STATIC_LIBRARY) &&
+ (tgt->GetType() != cmStateEnums::SHARED_LIBRARY) &&
+ (tgt->GetType() != cmStateEnums::UNKNOWN_LIBRARY) &&
+ (tgt->GetType() != cmStateEnums::INTERFACE_LIBRARY) &&
+ !tgt->IsExecutableWithExports()) {
+ std::ostringstream e;
+ e << "Target \"" << lib << "\" of type "
+ << cmState::GetTargetTypeName(tgt->GetType())
+ << " may not be linked into another target. One may link only to "
+ "INTERFACE, STATIC or SHARED libraries, or to executables with the "
+ "ENABLE_EXPORTS property set.";
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
}
- if (this->CurrentProcessingState == ProcessingLinkLibraries) {
- this->Target->AppendProperty(
- "INTERFACE_LINK_LIBRARIES",
- this->Target->GetDebugGeneratorExpressions(lib, llt).c_str());
- return true;
- }
- if (this->CurrentProcessingState != ProcessingKeywordPublicInterface &&
- this->CurrentProcessingState != ProcessingPlainPublicInterface) {
- if (this->Target->GetType() == cmStateEnums::STATIC_LIBRARY) {
- std::string configLib =
- this->Target->GetDebugGeneratorExpressions(lib, llt);
- if (cmGeneratorExpression::IsValidTargetName(lib) ||
- cmGeneratorExpression::Find(lib) != std::string::npos) {
- configLib = "$<LINK_ONLY:" + configLib + ">";
- }
- this->Target->AppendProperty("INTERFACE_LINK_LIBRARIES",
- configLib.c_str());
+ this->Target->AddLinkLibrary(*this->Makefile, lib, llt);
+ }
+
+ // Handle (additional) case where the command was called with PRIVATE /
+ // LINK_PRIVATE and stop its processing. (The "INTERFACE_LINK_LIBRARIES"
+ // property of the target on the LHS shall only be populated if it is a
+ // STATIC library.)
+ if (this->CurrentProcessingState == ProcessingKeywordPrivateInterface ||
+ this->CurrentProcessingState == ProcessingPlainPrivateInterface) {
+ if (this->Target->GetType() == cmStateEnums::STATIC_LIBRARY) {
+ std::string configLib =
+ this->Target->GetDebugGeneratorExpressions(lib, llt);
+ if (cmGeneratorExpression::IsValidTargetName(lib) ||
+ cmGeneratorExpression::Find(lib) != std::string::npos) {
+ configLib = "$<LINK_ONLY:" + configLib + ">";
}
- // Not a 'public' or 'interface' library. Do not add to interface
- // property.
- return true;
+ this->Target->AppendProperty("INTERFACE_LINK_LIBRARIES",
+ configLib.c_str());
}
+ return true;
}
+ // Handle general case where the command was called with another keyword than
+ // PRIVATE / LINK_PRIVATE or none at all. (The "INTERFACE_LINK_LIBRARIES"
+ // property of the target on the LHS shall be populated.)
this->Target->AppendProperty(
"INTERFACE_LINK_LIBRARIES",
this->Target->GetDebugGeneratorExpressions(lib, llt).c_str());
+ // Stop processing if called without any keyword.
+ if (this->CurrentProcessingState == ProcessingLinkLibraries) {
+ return true;
+ }
+ // Stop processing if policy CMP0022 is set to NEW.
const cmPolicies::PolicyStatus policy22Status =
this->Target->GetPolicyStatusCMP0022();
-
if (policy22Status != cmPolicies::OLD &&
policy22Status != cmPolicies::WARN) {
return true;
}
-
+ // Stop processing if called with an INTERFACE library on the LHS.
if (this->Target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
return true;
}
- // Get the list of configurations considered to be DEBUG.
- std::vector<std::string> debugConfigs =
- this->Makefile->GetCMakeInstance()->GetDebugConfigs();
- std::string prop;
-
- // Include this library in the link interface for the target.
- 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;
- this->Target->AppendProperty(prop, lib.c_str());
+ // Handle (additional) backward-compatibility case where the command was
+ // called with PUBLIC / INTERFACE / LINK_PUBLIC / LINK_INTERFACE_LIBRARIES.
+ // (The policy CMP0022 is not set to NEW.)
+ {
+ // Get the list of configurations considered to be DEBUG.
+ std::vector<std::string> debugConfigs =
+ this->Makefile->GetCMakeInstance()->GetDebugConfigs();
+ std::string prop;
+
+ // Include this library in the link interface for the target.
+ 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;
+ this->Target->AppendProperty(prop, lib.c_str());
+ }
}
- }
- if (llt == OPTIMIZED_LibraryType || llt == GENERAL_LibraryType) {
- // Put in the non-DEBUG configuration interfaces.
- this->Target->AppendProperty("LINK_INTERFACE_LIBRARIES", lib.c_str());
-
- // 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;
- if (!this->Target->GetProperty(prop)) {
- this->Target->SetProperty(prop, "");
+ if (llt == OPTIMIZED_LibraryType || llt == GENERAL_LibraryType) {
+ // Put in the non-DEBUG configuration interfaces.
+ this->Target->AppendProperty("LINK_INTERFACE_LIBRARIES", lib.c_str());
+
+ // 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;
+ if (!this->Target->GetProperty(prop)) {
+ this->Target->SetProperty(prop, "");
+ }
}
}
}
diff --git a/Source/cmTargetLinkLibrariesCommand.h b/Source/cmTargetLinkLibrariesCommand.h
index f41af49..a2f3ecd 100644
--- a/Source/cmTargetLinkLibrariesCommand.h
+++ b/Source/cmTargetLinkLibrariesCommand.h
@@ -20,6 +20,9 @@ class cmTarget;
* cmTargetLinkLibrariesCommand is used to specify a list of libraries to link
* into executable(s) or shared objects. The names of the libraries
* should be those defined by the LIBRARY(library) command(s).
+ *
+ * Additionally, it allows to propagate usage-requirements (including link
+ * libraries) from one target into another.
*/
class cmTargetLinkLibrariesCommand : public cmCommand
{
diff --git a/Source/cmTargetPropertyComputer.cxx b/Source/cmTargetPropertyComputer.cxx
index ed9026e..06ce0b1 100644
--- a/Source/cmTargetPropertyComputer.cxx
+++ b/Source/cmTargetPropertyComputer.cxx
@@ -3,6 +3,7 @@
#include "cmTargetPropertyComputer.h"
+#include <cctype>
#include <sstream>
#include <unordered_set>
@@ -49,6 +50,12 @@ bool cmTargetPropertyComputer::WhiteListedInterfaceProperty(
if (cmHasLiteralPrefix(prop, "INTERFACE_")) {
return true;
}
+ if (cmHasLiteralPrefix(prop, "_")) {
+ return true;
+ }
+ if (std::islower(prop[0])) {
+ return true;
+ }
static std::unordered_set<std::string> builtIns;
if (builtIns.empty()) {
builtIns.insert("COMPATIBLE_INTERFACE_BOOL");
diff --git a/Source/cmUVHandlePtr.cxx b/Source/cmUVHandlePtr.cxx
new file mode 100644
index 0000000..eb70416
--- /dev/null
+++ b/Source/cmUVHandlePtr.cxx
@@ -0,0 +1,227 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#define cmUVHandlePtr_cxx
+#include "cmUVHandlePtr.h"
+
+#include <assert.h>
+#include <mutex>
+#include <stdlib.h>
+
+#include "cm_uv.h"
+
+namespace cm {
+
+static void close_delete(uv_handle_t* h)
+{
+ free(h);
+}
+
+template <typename T>
+static void default_delete(T* type_handle)
+{
+ auto handle = reinterpret_cast<uv_handle_t*>(type_handle);
+ if (handle) {
+ assert(!uv_is_closing(handle));
+ if (!uv_is_closing(handle)) {
+ uv_close(handle, &close_delete);
+ }
+ }
+}
+
+/**
+ * Encapsulates delete logic for a given handle type T
+ */
+template <typename T>
+struct uv_handle_deleter
+{
+ void operator()(T* type_handle) const { default_delete(type_handle); }
+};
+
+template <typename T>
+void uv_handle_ptr_base_<T>::allocate(void* data)
+{
+ reset();
+
+ /*
+ We use calloc since we know all these types are c structs
+ and we just want to 0 init them. New would do the same thing;
+ but casting from uv_handle_t to certain other types -- namely
+ uv_timer_t -- triggers a cast_align warning on certain systems.
+ */
+ handle.reset(static_cast<T*>(calloc(1, sizeof(T))), uv_handle_deleter<T>());
+ handle->data = data;
+}
+
+template <typename T>
+void uv_handle_ptr_base_<T>::reset()
+{
+ handle.reset();
+}
+
+template <typename T>
+uv_handle_ptr_base_<T>::operator uv_handle_t*()
+{
+ return reinterpret_cast<uv_handle_t*>(handle.get());
+}
+
+template <typename T>
+T* uv_handle_ptr_base_<T>::operator->() const noexcept
+{
+ return handle.get();
+}
+
+template <typename T>
+T* uv_handle_ptr_base_<T>::get() const
+{
+ return handle.get();
+}
+
+template <typename T>
+uv_handle_ptr_<T>::operator T*() const
+{
+ return this->handle.get();
+}
+
+#ifdef CMAKE_BUILD_WITH_CMAKE
+template <>
+struct uv_handle_deleter<uv_async_t>
+{
+ /***
+ * Wile uv_async_send is itself thread-safe, there are
+ * no strong guarantees that close hasn't already been
+ * called on the handle; and that it might be deleted
+ * as the send call goes through. This mutex guards
+ * against that.
+ *
+ * The shared_ptr here is to allow for copy construction
+ * which is mandated by the standard for Deleter on
+ * shared_ptrs.
+ */
+ std::shared_ptr<std::mutex> handleMutex;
+
+ uv_handle_deleter()
+ : handleMutex(std::make_shared<std::mutex>())
+ {
+ }
+
+ void operator()(uv_async_t* handle)
+ {
+ std::lock_guard<std::mutex> lock(*handleMutex);
+ default_delete(handle);
+ }
+};
+
+void uv_async_ptr::send()
+{
+ auto deleter = std::get_deleter<uv_handle_deleter<uv_async_t>>(this->handle);
+ assert(deleter);
+
+ std::lock_guard<std::mutex> lock(*deleter->handleMutex);
+ if (this->handle) {
+ uv_async_send(*this);
+ }
+}
+
+int uv_async_ptr::init(uv_loop_t& loop, uv_async_cb async_cb, void* data)
+{
+ allocate(data);
+ return uv_async_init(&loop, handle.get(), async_cb);
+}
+#endif
+
+template <>
+struct uv_handle_deleter<uv_signal_t>
+{
+ void operator()(uv_signal_t* handle) const
+ {
+ if (handle) {
+ uv_signal_stop(handle);
+ default_delete(handle);
+ }
+ }
+};
+
+int uv_signal_ptr::init(uv_loop_t& loop, void* data)
+{
+ allocate(data);
+ return uv_signal_init(&loop, handle.get());
+}
+
+int uv_signal_ptr::start(uv_signal_cb cb, int signum)
+{
+ assert(handle);
+ return uv_signal_start(*this, cb, signum);
+}
+
+void uv_signal_ptr::stop()
+{
+ if (handle) {
+ uv_signal_stop(*this);
+ }
+}
+
+int uv_pipe_ptr::init(uv_loop_t& loop, int ipc, void* data)
+{
+ allocate(data);
+ return uv_pipe_init(&loop, *this, ipc);
+}
+
+uv_pipe_ptr::operator uv_stream_t*() const
+{
+ return reinterpret_cast<uv_stream_t*>(handle.get());
+}
+
+#ifdef CMAKE_BUILD_WITH_CMAKE
+int uv_process_ptr::spawn(uv_loop_t& loop, uv_process_options_t const& options,
+ void* data)
+{
+ allocate(data);
+ return uv_spawn(&loop, *this, &options);
+}
+
+int uv_timer_ptr::init(uv_loop_t& loop, void* data)
+{
+ allocate(data);
+ return uv_timer_init(&loop, *this);
+}
+
+int uv_timer_ptr::start(uv_timer_cb cb, uint64_t timeout, uint64_t repeat)
+{
+ assert(handle);
+ return uv_timer_start(*this, cb, timeout, repeat);
+}
+
+uv_tty_ptr::operator uv_stream_t*() const
+{
+ return reinterpret_cast<uv_stream_t*>(handle.get());
+}
+
+int uv_tty_ptr::init(uv_loop_t& loop, int fd, int readable, void* data)
+{
+ allocate(data);
+ return uv_tty_init(&loop, *this, fd, readable);
+}
+#endif
+
+template class uv_handle_ptr_base_<uv_handle_t>;
+
+#define UV_HANDLE_PTR_INSTANTIATE_EXPLICIT(NAME) \
+ template class uv_handle_ptr_base_<uv_##NAME##_t>; \
+ template class uv_handle_ptr_<uv_##NAME##_t>;
+
+UV_HANDLE_PTR_INSTANTIATE_EXPLICIT(signal)
+
+UV_HANDLE_PTR_INSTANTIATE_EXPLICIT(pipe)
+
+UV_HANDLE_PTR_INSTANTIATE_EXPLICIT(stream)
+
+#ifdef CMAKE_BUILD_WITH_CMAKE
+UV_HANDLE_PTR_INSTANTIATE_EXPLICIT(async)
+
+UV_HANDLE_PTR_INSTANTIATE_EXPLICIT(process)
+
+UV_HANDLE_PTR_INSTANTIATE_EXPLICIT(timer)
+
+UV_HANDLE_PTR_INSTANTIATE_EXPLICIT(tty)
+#endif
+}
diff --git a/Source/cmUVHandlePtr.h b/Source/cmUVHandlePtr.h
new file mode 100644
index 0000000..a6ce565
--- /dev/null
+++ b/Source/cmUVHandlePtr.h
@@ -0,0 +1,222 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#pragma once
+#include "cmConfigure.h" // IWYU pragma: keep
+
+#include <algorithm>
+#include <cstddef>
+#include <cstdint>
+#include <memory>
+#include <type_traits>
+
+#include "cm_uv.h"
+
+#define CM_PERFECT_FWD_CTOR(Class, FwdTo) \
+ template <typename... Args> \
+ Class(Args&&... args) \
+ : FwdTo(std::forward<Args>(args)...) \
+ { \
+ }
+
+namespace cm {
+
+/***
+* RAII class to simplify and insure the safe usage of uv_*_t types. This
+* includes making sure resources are properly freed and contains casting
+* operators which allow for passing into relevant uv_* functions.
+*
+*@tparam T actual uv_*_t type represented.
+*/
+template <typename T>
+class uv_handle_ptr_base_
+{
+protected:
+ template <typename _T>
+ friend class uv_handle_ptr_base_;
+
+ /**
+ * This must be a pointer type since the handle can outlive this class.
+ * When uv_close is eventually called on the handle, the memory the
+ * handle inhabits must be valid until the close callback is called
+ * which can be later on in the loop.
+ */
+ std::shared_ptr<T> handle;
+
+ /**
+ * Allocate memory for the type and optionally set it's 'data' pointer.
+ * Protected since this should only be called for an appropriate 'init'
+ * call.
+ *
+ * @param data data pointer to set
+ */
+ void allocate(void* data = nullptr);
+
+public:
+ CM_DISABLE_COPY(uv_handle_ptr_base_)
+ uv_handle_ptr_base_(uv_handle_ptr_base_&&) noexcept;
+ uv_handle_ptr_base_& operator=(uv_handle_ptr_base_&&) noexcept;
+
+ /**
+ * This move constructor allows us to move out of a more specialized
+ * uv type into a less specialized one. The only constraint is that
+ * the right hand side is castable to T.
+ *
+ * This allows you to return uv_handle_ptr or uv_stream_ptr from a function
+ * that initializes something like uv_pipe_ptr or uv_tcp_ptr and interact
+ * and clean up after it without caring about the exact type.
+ */
+ template <typename S, typename = typename std::enable_if<
+ std::is_rvalue_reference<S&&>::value>::type>
+ uv_handle_ptr_base_(S&& rhs)
+ {
+ // This will force a compiler error if rhs doesn't have a casting
+ // operator to get T*
+ this->handle = std::shared_ptr<T>(rhs.handle, rhs);
+ rhs.handle.reset();
+ }
+
+ // Dtor and ctor need to be inline defined like this for default ctors and
+ // dtors to work.
+ uv_handle_ptr_base_() {}
+ uv_handle_ptr_base_(std::nullptr_t) {}
+ ~uv_handle_ptr_base_() { reset(); }
+
+ /**
+ * Properly close the handle if needed and sets the inner handle to nullptr
+ */
+ void reset();
+
+ /**
+ * Allow less verbose calling of uv_handle_* functions
+ * @return reinterpreted handle
+ */
+ operator uv_handle_t*();
+
+ T* get() const;
+ T* operator->() const noexcept;
+};
+
+template <typename T>
+inline uv_handle_ptr_base_<T>::uv_handle_ptr_base_(
+ uv_handle_ptr_base_<T>&&) noexcept = default;
+template <typename T>
+inline uv_handle_ptr_base_<T>& uv_handle_ptr_base_<T>::operator=(
+ uv_handle_ptr_base_<T>&&) noexcept = default;
+
+/**
+ * While uv_handle_ptr_base_ only exposes uv_handle_t*, this exposes uv_T_t*
+ * too. It is broken out like this so we can reuse most of the code for the
+ * uv_handle_ptr class.
+ */
+template <typename T>
+class uv_handle_ptr_ : public uv_handle_ptr_base_<T>
+{
+ template <typename _T>
+ friend class uv_handle_ptr_;
+
+public:
+ CM_PERFECT_FWD_CTOR(uv_handle_ptr_, uv_handle_ptr_base_<T>);
+
+ /***
+ * Allow less verbose calling of uv_<T> functions
+ * @return reinterpreted handle
+ */
+ operator T*() const;
+};
+
+/***
+ * This specialization is required to avoid duplicate 'operator uv_handle_t*()'
+ * declarations
+ */
+template <>
+class uv_handle_ptr_<uv_handle_t> : public uv_handle_ptr_base_<uv_handle_t>
+{
+public:
+ CM_PERFECT_FWD_CTOR(uv_handle_ptr_, uv_handle_ptr_base_<uv_handle_t>);
+};
+
+class uv_async_ptr : public uv_handle_ptr_<uv_async_t>
+{
+public:
+ CM_PERFECT_FWD_CTOR(uv_async_ptr, uv_handle_ptr_<uv_async_t>);
+
+ int init(uv_loop_t& loop, uv_async_cb async_cb, void* data = nullptr);
+
+ void send();
+};
+
+struct uv_signal_ptr : public uv_handle_ptr_<uv_signal_t>
+{
+ CM_PERFECT_FWD_CTOR(uv_signal_ptr, uv_handle_ptr_<uv_signal_t>);
+
+ int init(uv_loop_t& loop, void* data = nullptr);
+
+ int start(uv_signal_cb cb, int signum);
+
+ void stop();
+};
+
+struct uv_pipe_ptr : public uv_handle_ptr_<uv_pipe_t>
+{
+ CM_PERFECT_FWD_CTOR(uv_pipe_ptr, uv_handle_ptr_<uv_pipe_t>);
+
+ operator uv_stream_t*() const;
+
+ int init(uv_loop_t& loop, int ipc, void* data = nullptr);
+};
+
+struct uv_process_ptr : public uv_handle_ptr_<uv_process_t>
+{
+ CM_PERFECT_FWD_CTOR(uv_process_ptr, uv_handle_ptr_<uv_process_t>);
+
+ int spawn(uv_loop_t& loop, uv_process_options_t const& options,
+ void* data = nullptr);
+};
+
+struct uv_timer_ptr : public uv_handle_ptr_<uv_timer_t>
+{
+ CM_PERFECT_FWD_CTOR(uv_timer_ptr, uv_handle_ptr_<uv_timer_t>);
+
+ int init(uv_loop_t& loop, void* data = nullptr);
+
+ int start(uv_timer_cb cb, uint64_t timeout, uint64_t repeat);
+};
+
+struct uv_tty_ptr : public uv_handle_ptr_<uv_tty_t>
+{
+ CM_PERFECT_FWD_CTOR(uv_tty_ptr, uv_handle_ptr_<uv_tty_t>);
+
+ operator uv_stream_t*() const;
+
+ int init(uv_loop_t& loop, int fd, int readable, void* data = nullptr);
+};
+
+typedef uv_handle_ptr_<uv_stream_t> uv_stream_ptr;
+typedef uv_handle_ptr_<uv_handle_t> uv_handle_ptr;
+
+#ifndef cmUVHandlePtr_cxx
+
+extern template class uv_handle_ptr_base_<uv_handle_t>;
+
+#define UV_HANDLE_PTR_INSTANTIATE_EXTERN(NAME) \
+ extern template class uv_handle_ptr_base_<uv_##NAME##_t>; \
+ extern template class uv_handle_ptr_<uv_##NAME##_t>;
+
+UV_HANDLE_PTR_INSTANTIATE_EXTERN(async)
+
+UV_HANDLE_PTR_INSTANTIATE_EXTERN(signal)
+
+UV_HANDLE_PTR_INSTANTIATE_EXTERN(pipe)
+
+UV_HANDLE_PTR_INSTANTIATE_EXTERN(process)
+
+UV_HANDLE_PTR_INSTANTIATE_EXTERN(stream)
+
+UV_HANDLE_PTR_INSTANTIATE_EXTERN(timer)
+
+UV_HANDLE_PTR_INSTANTIATE_EXTERN(tty)
+
+#undef UV_HANDLE_PTR_INSTANTIATE_EXTERN
+
+#endif
+}
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index caeeeb9..8589a96 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -52,6 +52,7 @@ static std::string cmVS10EscapeComment(std::string comment)
case '>': /* no break */
case '^':
echoable += '^'; /* no break */
+ CM_FALLTHROUGH;
default:
echoable += *c;
break;
@@ -66,11 +67,14 @@ static bool cmVS10IsTargetsFile(std::string const& path)
return cmSystemTools::Strucmp(ext.c_str(), ".targets") == 0;
}
-static std::string computeProjectFileExtension(cmGeneratorTarget const* t)
+static std::string computeProjectFileExtension(cmGeneratorTarget const* t,
+ const std::string& config)
{
std::string res;
res = ".vcxproj";
- if (cmGlobalVisualStudioGenerator::TargetIsCSharpOnly(t)) {
+ std::string lang = t->GetLinkerLanguage(config);
+ if (cmGlobalVisualStudioGenerator::TargetIsCSharpOnly(t) ||
+ lang == "CSharp") {
res = ".csproj";
}
return res;
@@ -199,8 +203,8 @@ void cmVisualStudio10TargetGenerator::Generate()
this->GeneratorTarget->GetProperty("EXTERNAL_MSPROJECT")) {
return;
}
- this->ProjectFileExtension =
- computeProjectFileExtension(this->GeneratorTarget);
+ this->ProjectFileExtension = computeProjectFileExtension(
+ this->GeneratorTarget, *this->Configurations.begin());
if (this->ProjectFileExtension == ".vcxproj") {
this->ProjectType = vcxproj;
this->Managed = false;
@@ -1393,7 +1397,8 @@ void cmVisualStudio10TargetGenerator::WriteGroups()
std::string path = this->LocalGenerator->GetCurrentBinaryDirectory();
path += "/";
path += this->Name;
- path += computeProjectFileExtension(this->GeneratorTarget);
+ path += computeProjectFileExtension(this->GeneratorTarget,
+ *this->Configurations.begin());
path += ".filters";
cmGeneratedFileStream fout(path.c_str());
fout.SetCopyIfDifferent(true);
@@ -2061,14 +2066,15 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
std::string flags;
bool configDependentFlags = false;
std::string defines;
+ bool configDependentDefines = false;
if (const char* cflags = sf.GetProperty("COMPILE_FLAGS")) {
-
- if (cmGeneratorExpression::Find(cflags) != std::string::npos) {
- configDependentFlags = true;
- }
+ configDependentFlags =
+ cmGeneratorExpression::Find(cflags) != std::string::npos;
flags += cflags;
}
if (const char* cdefs = sf.GetProperty("COMPILE_DEFINITIONS")) {
+ configDependentDefines =
+ cmGeneratorExpression::Find(cdefs) != std::string::npos;
defines += cdefs;
}
std::string lang =
@@ -2118,12 +2124,13 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
if (!configDefines.empty()) {
configDefines += ";";
}
+ configDependentDefines |=
+ cmGeneratorExpression::Find(ccdefs) != std::string::npos;
configDefines += ccdefs;
}
// if we have flags or defines for this config then
// use them
- if (!flags.empty() || configDependentFlags || !configDefines.empty() ||
- compileAs || noWinRT) {
+ if (!flags.empty() || !configDefines.empty() || compileAs || noWinRT) {
(*this->BuildFileStream) << firstString;
firstString = ""; // only do firstString once
hasFlags = true;
@@ -2144,6 +2151,8 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
} else if (srclang == "CSharp") {
flagtable = gg->GetCSharpFlagTable();
}
+ cmGeneratorExpressionInterpreter genexInterpreter(
+ this->LocalGenerator, this->GeneratorTarget, *config);
cmVisualStudioGeneratorOptions clOptions(
this->LocalGenerator, cmVisualStudioGeneratorOptions::Compiler,
flagtable, 0, this);
@@ -2154,11 +2163,7 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
clOptions.AddFlag("CompileAsWinRT", "false");
}
if (configDependentFlags) {
- cmGeneratorExpression ge;
- std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(flags);
- std::string evaluatedFlags = cge->Evaluate(
- this->LocalGenerator, *config, false, this->GeneratorTarget);
- clOptions.Parse(evaluatedFlags.c_str());
+ clOptions.Parse(genexInterpreter.Evaluate(flags));
} else {
clOptions.Parse(flags.c_str());
}
@@ -2170,7 +2175,11 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
clOptions.AppendFlag("DisableSpecificWarnings",
"%(DisableSpecificWarnings)");
}
- clOptions.AddDefines(configDefines.c_str());
+ if (configDependentDefines) {
+ clOptions.AddDefines(genexInterpreter.Evaluate(configDefines));
+ } else {
+ clOptions.AddDefines(configDefines.c_str());
+ }
clOptions.SetConfiguration((*config).c_str());
clOptions.PrependInheritedString("AdditionalOptions");
clOptions.OutputFlagMap(*this->BuildFileStream, " ");
@@ -3670,7 +3679,7 @@ void cmVisualStudio10TargetGenerator::WriteProjectReferences()
path = lg->GetCurrentBinaryDirectory();
path += "/";
path += dt->GetName();
- path += computeProjectFileExtension(dt);
+ path += computeProjectFileExtension(dt, *this->Configurations.begin());
}
this->ConvertToWindowsSlash(path);
(*this->BuildFileStream) << cmVS10EscapeXML(path) << "\">\n";
diff --git a/Source/cm_thread.hxx b/Source/cm_thread.hxx
index b8c25c7..84e6a5c 100644
--- a/Source/cm_thread.hxx
+++ b/Source/cm_thread.hxx
@@ -7,36 +7,11 @@
#include "cm_uv.h"
namespace cm {
-class mutex
-{
- uv_mutex_t _M_;
-
-public:
- mutex() { uv_mutex_init(&_M_); }
- ~mutex() { uv_mutex_destroy(&_M_); }
-
- void lock() { uv_mutex_lock(&_M_); }
-
- void unlock() { uv_mutex_unlock(&_M_); }
-};
-
-template <typename T>
-class lock_guard
-{
- T& _mutex;
-
-public:
- lock_guard(T& m)
- : _mutex(m)
- {
- _mutex.lock();
- }
- ~lock_guard() { _mutex.unlock(); }
-};
class shared_mutex
{
uv_rwlock_t _M_;
+ CM_DISABLE_COPY(shared_mutex)
public:
shared_mutex() { uv_rwlock_init(&_M_); }
@@ -55,6 +30,7 @@ template <typename T>
class shared_lock
{
T& _mutex;
+ CM_DISABLE_COPY(shared_lock)
public:
shared_lock(T& m)
@@ -64,15 +40,5 @@ public:
}
~shared_lock() { _mutex.unlock_shared(); }
};
-
-template <typename T>
-class unique_lock : public lock_guard<T>
-{
-public:
- unique_lock(T& m)
- : lock_guard<T>(m)
- {
- }
-};
}
#endif
diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx
index 3d9f65a..b78fbe6 100644
--- a/Source/cmcmd.cxx
+++ b/Source/cmcmd.cxx
@@ -270,10 +270,12 @@ static int HandleCppLint(const std::string& runCmd,
<< "\n";
return 1;
}
-
+ std::cerr << "Warning: cpplint diagnostics:\n";
// Output the output from cpplint to stderr
std::cerr << stdOut;
- return ret;
+ // always return 0 so the build can continue as cpplint returns non-zero
+ // for any warning
+ return 0;
}
static int HandleCppCheck(const std::string& runCmd,
diff --git a/Source/kwsys/CMakeLists.txt b/Source/kwsys/CMakeLists.txt
index 51f4088..351e38d 100644
--- a/Source/kwsys/CMakeLists.txt
+++ b/Source/kwsys/CMakeLists.txt
@@ -705,9 +705,13 @@ ENDIF()
# selected components. Initialize with required components.
SET(KWSYS_CLASSES)
SET(KWSYS_H_FILES Configure SharedForward)
-SET(KWSYS_HXX_FILES Configure String
- hashtable hash_fun hash_map hash_set
- )
+SET(KWSYS_HXX_FILES Configure String)
+
+IF(NOT CMake_SOURCE_DIR)
+ SET(KWSYS_HXX_FILES ${KWSYS_HXX_FILES}
+ hashtable hash_fun hash_map hash_set
+ )
+ENDIF()
# Add selected C++ classes.
SET(cppclasses
@@ -1027,12 +1031,13 @@ IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR)
ENDFOREACH()
# C++ tests
- IF(NOT WATCOM)
+ IF(NOT WATCOM AND NOT CMake_SOURCE_DIR)
SET(KWSYS_CXX_TESTS
testHashSTL
)
ENDIF()
SET(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS}
+ testConfigure
testSystemTools
testCommandLineArguments
testCommandLineArguments1
diff --git a/Source/kwsys/Configure.hxx.in b/Source/kwsys/Configure.hxx.in
index 1c07a4e..1e67874 100644
--- a/Source/kwsys/Configure.hxx.in
+++ b/Source/kwsys/Configure.hxx.in
@@ -12,6 +12,31 @@
#define @KWSYS_NAMESPACE@_CXX_HAS_EXT_STDIO_FILEBUF_H \
@KWSYS_CXX_HAS_EXT_STDIO_FILEBUF_H@
+#if defined(__SUNPRO_CC) && __SUNPRO_CC > 0x5130 && defined(__has_attribute)
+#define @KWSYS_NAMESPACE@__has_cpp_attribute(x) __has_attribute(x)
+#elif defined(__has_cpp_attribute)
+#define @KWSYS_NAMESPACE@__has_cpp_attribute(x) __has_cpp_attribute(x)
+#else
+#define @KWSYS_NAMESPACE@__has_cpp_attribute(x) 0
+#endif
+
+#ifndef @KWSYS_NAMESPACE@_FALLTHROUGH
+#if __cplusplus >= 201703L && @KWSYS_NAMESPACE@__has_cpp_attribute(fallthrough)
+#define @KWSYS_NAMESPACE@_FALLTHROUGH [[fallthrough]]
+#elif __cplusplus >= 201103L && \
+ @KWSYS_NAMESPACE@__has_cpp_attribute(gnu::fallthrough)
+#define @KWSYS_NAMESPACE@_FALLTHROUGH [[gnu::fallthrough]]
+#elif __cplusplus >= 201103L && \
+ @KWSYS_NAMESPACE@__has_cpp_attribute(clang::fallthrough)
+#define @KWSYS_NAMESPACE@_FALLTHROUGH [[clang::fallthrough]]
+#endif
+#endif
+#ifndef @KWSYS_NAMESPACE@_FALLTHROUGH
+#define @KWSYS_NAMESPACE@_FALLTHROUGH static_cast<void>(0)
+#endif
+
+#undef @KWSYS_NAMESPACE@__has_cpp_attribute
+
/* If building a C++ file in kwsys itself, give the source file
access to the macros without a configured namespace. */
#if defined(KWSYS_NAMESPACE)
@@ -22,6 +47,7 @@
#define KWSYS_STL_HAS_WSTRING @KWSYS_NAMESPACE@_STL_HAS_WSTRING
#define KWSYS_CXX_HAS_EXT_STDIO_FILEBUF_H \
@KWSYS_NAMESPACE@_CXX_HAS_EXT_STDIO_FILEBUF_H
+#define KWSYS_FALLTHROUGH @KWSYS_NAMESPACE@_FALLTHROUGH
#endif
#endif
diff --git a/Source/kwsys/ConsoleBuf.hxx.in b/Source/kwsys/ConsoleBuf.hxx.in
index 46d65a8..cf68146 100644
--- a/Source/kwsys/ConsoleBuf.hxx.in
+++ b/Source/kwsys/ConsoleBuf.hxx.in
@@ -264,6 +264,7 @@ private:
if (m_isConsoleInput) {
break;
}
+ @KWSYS_NAMESPACE@_FALLTHROUGH;
case FILE_TYPE_PIPE:
m_activeInputCodepage = input_pipe_codepage;
break;
@@ -290,6 +291,7 @@ private:
if (m_isConsoleOutput) {
break;
}
+ @KWSYS_NAMESPACE@_FALLTHROUGH;
case FILE_TYPE_PIPE:
m_activeOutputCodepage = output_pipe_codepage;
break;
diff --git a/Source/kwsys/RegularExpression.cxx b/Source/kwsys/RegularExpression.cxx
index 26e84e0..fa3551c 100644
--- a/Source/kwsys/RegularExpression.cxx
+++ b/Source/kwsys/RegularExpression.cxx
@@ -45,9 +45,9 @@ RegularExpression::RegularExpression(const RegularExpression& rxp)
this->program = new char[this->progsize]; // Allocate storage
for (ind = this->progsize; ind-- != 0;) // Copy regular expresion
this->program[ind] = rxp.program[ind];
- this->startp[0] = rxp.startp[0]; // Copy pointers into last
- this->endp[0] = rxp.endp[0]; // Successful "find" operation
- this->regmust = rxp.regmust; // Copy field
+ // Copy pointers into last successful "find" operation
+ this->regmatch = rxp.regmatch;
+ this->regmust = rxp.regmust; // Copy field
if (rxp.regmust != 0) {
char* dum = rxp.program;
ind = 0;
@@ -78,9 +78,9 @@ RegularExpression& RegularExpression::operator=(const RegularExpression& rxp)
this->program = new char[this->progsize]; // Allocate storage
for (ind = this->progsize; ind-- != 0;) // Copy regular expresion
this->program[ind] = rxp.program[ind];
- this->startp[0] = rxp.startp[0]; // Copy pointers into last
- this->endp[0] = rxp.endp[0]; // Successful "find" operation
- this->regmust = rxp.regmust; // Copy field
+ // Copy pointers into last successful "find" operation
+ this->regmatch = rxp.regmatch;
+ this->regmust = rxp.regmust; // Copy field
if (rxp.regmust != 0) {
char* dum = rxp.program;
ind = 0;
@@ -123,8 +123,9 @@ bool RegularExpression::deep_equal(const RegularExpression& rxp) const
while (ind-- != 0) // Else while still characters
if (this->program[ind] != rxp.program[ind]) // If regexp are different
return false; // Return failure
- return (this->startp[0] == rxp.startp[0] && // Else if same start/end ptrs,
- this->endp[0] == rxp.endp[0]); // Return true
+ // Else if same start/end ptrs, return true
+ return (this->regmatch.start() == rxp.regmatch.start() &&
+ this->regmatch.end() == rxp.regmatch.end());
}
// The remaining code in this file is derived from the regular expression code
@@ -276,31 +277,35 @@ const unsigned char MAGIC = 0234;
/////////////////////////////////////////////////////////////////////////
/*
- * Global work variables for compile().
+ * Read only utility variables.
*/
-static const char* regparse; // Input-scan pointer.
-static int regnpar; // () count.
static char regdummy;
-static char* regcode; // Code-emit pointer; &regdummy = don't.
-static long regsize; // Code size.
+static char* const regdummyptr = &regdummy;
/*
- * Forward declarations for compile()'s friends.
+ * Utility class for RegularExpression::compile().
*/
-// #ifndef static
-// #define static static
-// #endif
-static char* reg(int, int*);
-static char* regbranch(int*);
-static char* regpiece(int*);
-static char* regatom(int*);
-static char* regnode(char);
+class RegExpCompile
+{
+public:
+ const char* regparse; // Input-scan pointer.
+ int regnpar; // () count.
+ char* regcode; // Code-emit pointer; regdummyptr = don't.
+ long regsize; // Code size.
+
+ char* reg(int, int*);
+ char* regbranch(int*);
+ char* regpiece(int*);
+ char* regatom(int*);
+ char* regnode(char);
+ void regc(char);
+ void reginsert(char, char*);
+ static void regtail(char*, const char*);
+ static void regoptail(char*, const char*);
+};
+
static const char* regnext(const char*);
static char* regnext(char*);
-static void regc(char);
-static void reginsert(char, char*);
-static void regtail(char*, const char*);
-static void regoptail(char*, const char*);
#ifdef STRCSPN
static int strcspn();
@@ -337,19 +342,20 @@ bool RegularExpression::compile(const char* exp)
}
// First pass: determine size, legality.
- regparse = exp;
- regnpar = 1;
- regsize = 0L;
- regcode = &regdummy;
- regc(static_cast<char>(MAGIC));
- if (!reg(0, &flags)) {
+ RegExpCompile comp;
+ comp.regparse = exp;
+ comp.regnpar = 1;
+ comp.regsize = 0L;
+ comp.regcode = regdummyptr;
+ comp.regc(static_cast<char>(MAGIC));
+ if (!comp.reg(0, &flags)) {
printf("RegularExpression::compile(): Error in compile.\n");
return false;
}
- this->startp[0] = this->endp[0] = this->searchstring = 0;
+ this->regmatch.clear();
// Small enough for pointer-storage convention?
- if (regsize >= 32767L) { // Probably could be 65535L.
+ if (comp.regsize >= 32767L) { // Probably could be 65535L.
// RAISE Error, SYM(RegularExpression), SYM(Expr_Too_Big),
printf("RegularExpression::compile(): Expression too big.\n");
return false;
@@ -360,8 +366,8 @@ bool RegularExpression::compile(const char* exp)
if (this->program != 0)
delete[] this->program;
//#endif
- this->program = new char[regsize];
- this->progsize = static_cast<int>(regsize);
+ this->program = new char[comp.regsize];
+ this->progsize = static_cast<int>(comp.regsize);
if (this->program == 0) {
// RAISE Error, SYM(RegularExpression), SYM(Out_Of_Memory),
@@ -370,11 +376,11 @@ bool RegularExpression::compile(const char* exp)
}
// Second pass: emit code.
- regparse = exp;
- regnpar = 1;
- regcode = this->program;
- regc(static_cast<char>(MAGIC));
- reg(0, &flags);
+ comp.regparse = exp;
+ comp.regnpar = 1;
+ comp.regcode = this->program;
+ comp.regc(static_cast<char>(MAGIC));
+ comp.reg(0, &flags);
// Dig out information for optimizations.
this->regstart = '\0'; // Worst-case defaults.
@@ -423,7 +429,7 @@ bool RegularExpression::compile(const char* exp)
* is a trifle forced, but the need to tie the tails of the branches to what
* follows makes it hard to avoid.
*/
-static char* reg(int paren, int* flagp)
+char* RegExpCompile::reg(int paren, int* flagp)
{
char* ret;
char* br;
@@ -435,7 +441,7 @@ static char* reg(int paren, int* flagp)
// Make an OPEN node, if parenthesized.
if (paren) {
- if (regnpar >= RegularExpression::NSUBEXP) {
+ if (regnpar >= RegularExpressionMatch::NSUBEXP) {
// RAISE Error, SYM(RegularExpression), SYM(Too_Many_Parens),
printf("RegularExpression::compile(): Too many parentheses.\n");
return 0;
@@ -501,7 +507,7 @@ static char* reg(int paren, int* flagp)
*
* Implements the concatenation operator.
*/
-static char* regbranch(int* flagp)
+char* RegExpCompile::regbranch(int* flagp)
{
char* ret;
char* chain;
@@ -538,7 +544,7 @@ static char* regbranch(int* flagp)
* It might seem that this node could be dispensed with entirely, but the
* endmarker role is not redundant.
*/
-static char* regpiece(int* flagp)
+char* RegExpCompile::regpiece(int* flagp)
{
char* ret;
char op;
@@ -605,7 +611,7 @@ static char* regpiece(int* flagp)
* faster to run. Backslashed characters are exceptions, each becoming a
* separate node; the code is simpler that way and it's not worth fixing.
*/
-static char* regatom(int* flagp)
+char* RegExpCompile::regatom(int* flagp)
{
char* ret;
int flags;
@@ -724,13 +730,13 @@ static char* regatom(int* flagp)
- regnode - emit a node
Location.
*/
-static char* regnode(char op)
+char* RegExpCompile::regnode(char op)
{
char* ret;
char* ptr;
ret = regcode;
- if (ret == &regdummy) {
+ if (ret == regdummyptr) {
regsize += 3;
return (ret);
}
@@ -747,9 +753,9 @@ static char* regnode(char op)
/*
- regc - emit (if appropriate) a byte of code
*/
-static void regc(char b)
+void RegExpCompile::regc(char b)
{
- if (regcode != &regdummy)
+ if (regcode != regdummyptr)
*regcode++ = b;
else
regsize++;
@@ -760,13 +766,13 @@ static void regc(char b)
*
* Means relocating the operand.
*/
-static void reginsert(char op, char* opnd)
+void RegExpCompile::reginsert(char op, char* opnd)
{
char* src;
char* dst;
char* place;
- if (regcode == &regdummy) {
+ if (regcode == regdummyptr) {
regsize += 3;
return;
}
@@ -786,13 +792,13 @@ static void reginsert(char op, char* opnd)
/*
- regtail - set the next-pointer at the end of a node chain
*/
-static void regtail(char* p, const char* val)
+void RegExpCompile::regtail(char* p, const char* val)
{
char* scan;
char* temp;
int offset;
- if (p == &regdummy)
+ if (p == regdummyptr)
return;
// Find last node.
@@ -815,10 +821,10 @@ static void regtail(char* p, const char* val)
/*
- regoptail - regtail on operand of first argument; nop if operandless
*/
-static void regoptail(char* p, const char* val)
+void RegExpCompile::regoptail(char* p, const char* val)
{
// "Operandless" and "op != BRANCH" are synonymous in practice.
- if (p == 0 || p == &regdummy || OP(p) != BRANCH)
+ if (p == 0 || p == regdummyptr || OP(p) != BRANCH)
return;
regtail(OPERAND(p), val);
}
@@ -830,34 +836,30 @@ static void regoptail(char* p, const char* val)
////////////////////////////////////////////////////////////////////////
/*
- * Global work variables for find().
+ * Utility class for RegularExpression::find().
*/
-static const char* reginput; // String-input pointer.
-static const char* regbol; // Beginning of input, for ^ check.
-static const char** regstartp; // Pointer to startp array.
-static const char** regendp; // Ditto for endp.
+class RegExpFind
+{
+public:
+ const char* reginput; // String-input pointer.
+ const char* regbol; // Beginning of input, for ^ check.
+ const char** regstartp; // Pointer to startp array.
+ const char** regendp; // Ditto for endp.
-/*
- * Forwards.
- */
-static int regtry(const char*, const char**, const char**, const char*);
-static int regmatch(const char*);
-static int regrepeat(const char*);
-
-#ifdef DEBUG
-int regnarrate = 0;
-void regdump();
-static char* regprop();
-#endif
+ int regtry(const char*, const char**, const char**, const char*);
+ int regmatch(const char*);
+ int regrepeat(const char*);
+};
// find -- Matches the regular expression to the given string.
// Returns true if found, and sets start and end indexes accordingly.
-
-bool RegularExpression::find(const char* string)
+bool RegularExpression::find(char const* string,
+ RegularExpressionMatch& rmatch) const
{
const char* s;
- this->searchstring = string;
+ rmatch.clear();
+ rmatch.searchstring = string;
if (!this->program) {
return false;
@@ -868,7 +870,7 @@ bool RegularExpression::find(const char* string)
// RAISE Error, SYM(RegularExpression), SYM(Internal_Error),
printf(
"RegularExpression::find(): Compiled regular expression corrupted.\n");
- return 0;
+ return false;
}
// If there is a "must appear" string, look for it.
@@ -880,42 +882,45 @@ bool RegularExpression::find(const char* string)
s++;
}
if (s == 0) // Not present.
- return (0);
+ return false;
}
+ RegExpFind regFind;
+
// Mark beginning of line for ^ .
- regbol = string;
+ regFind.regbol = string;
// Simplest case: anchored match need be tried only once.
if (this->reganch)
- return (regtry(string, this->startp, this->endp, this->program) != 0);
+ return (
+ regFind.regtry(string, rmatch.startp, rmatch.endp, this->program) != 0);
// Messy cases: unanchored match.
s = string;
if (this->regstart != '\0')
// We know what char it must start with.
while ((s = strchr(s, this->regstart)) != 0) {
- if (regtry(s, this->startp, this->endp, this->program))
- return (1);
+ if (regFind.regtry(s, rmatch.startp, rmatch.endp, this->program))
+ return true;
s++;
}
else
// We don't -- general case.
do {
- if (regtry(s, this->startp, this->endp, this->program))
- return (1);
+ if (regFind.regtry(s, rmatch.startp, rmatch.endp, this->program))
+ return true;
} while (*s++ != '\0');
// Failure.
- return (0);
+ return false;
}
/*
- regtry - try match at specific point
0 failure, 1 success
*/
-static int regtry(const char* string, const char** start, const char** end,
- const char* prog)
+int RegExpFind::regtry(const char* string, const char** start,
+ const char** end, const char* prog)
{
int i;
const char** sp1;
@@ -927,7 +932,7 @@ static int regtry(const char* string, const char** start, const char** end,
sp1 = start;
ep = end;
- for (i = RegularExpression::NSUBEXP; i > 0; i--) {
+ for (i = RegularExpressionMatch::NSUBEXP; i > 0; i--) {
*sp1++ = 0;
*ep++ = 0;
}
@@ -950,7 +955,7 @@ static int regtry(const char* string, const char** start, const char** end,
* by recursion.
* 0 failure, 1 success
*/
-static int regmatch(const char* prog)
+int RegExpFind::regmatch(const char* prog)
{
const char* scan; // Current node.
const char* next; // Next node.
@@ -1129,7 +1134,7 @@ static int regmatch(const char* prog)
/*
- regrepeat - repeatedly match something simple, report how many
*/
-static int regrepeat(const char* p)
+int RegExpFind::regrepeat(const char* p)
{
int count = 0;
const char* scan;
@@ -1176,7 +1181,7 @@ static const char* regnext(const char* p)
{
int offset;
- if (p == &regdummy)
+ if (p == regdummyptr)
return (0);
offset = NEXT(p);
@@ -1193,7 +1198,7 @@ static char* regnext(char* p)
{
int offset;
- if (p == &regdummy)
+ if (p == regdummyptr)
return (0);
offset = NEXT(p);
diff --git a/Source/kwsys/RegularExpression.hxx.in b/Source/kwsys/RegularExpression.hxx.in
index 763fdab..a3fe72d 100644
--- a/Source/kwsys/RegularExpression.hxx.in
+++ b/Source/kwsys/RegularExpression.hxx.in
@@ -34,6 +34,115 @@
namespace @KWSYS_NAMESPACE@ {
+// Forward declaration
+class RegularExpression;
+
+/** \class RegularExpressionMatch
+ * \brief Stores the pattern matches of a RegularExpression
+ */
+class @KWSYS_NAMESPACE@_EXPORT RegularExpressionMatch
+{
+public:
+ RegularExpressionMatch();
+
+ bool isValid() const;
+ void clear();
+
+ std::string::size_type start() const;
+ std::string::size_type end() const;
+ std::string::size_type start(int n) const;
+ std::string::size_type end(int n) const;
+ std::string match(int n) const;
+
+ enum
+ {
+ NSUBEXP = 10
+ };
+
+private:
+ friend class RegularExpression;
+ const char* startp[NSUBEXP];
+ const char* endp[NSUBEXP];
+ const char* searchstring;
+};
+
+/**
+ * \brief Creates an invalid match object
+ */
+inline RegularExpressionMatch::RegularExpressionMatch()
+{
+ startp[0] = 0;
+ endp[0] = 0;
+ searchstring = 0;
+}
+
+/**
+ * \brief Returns true if the match pointers are valid
+ */
+inline bool RegularExpressionMatch::isValid() const
+{
+ return (this->startp[0] != 0);
+}
+
+/**
+ * \brief Resets to the (invalid) construction state.
+ */
+inline void RegularExpressionMatch::clear()
+{
+ startp[0] = 0;
+ endp[0] = 0;
+ searchstring = 0;
+}
+
+/**
+ * \brief Returns the start index of the full match.
+ */
+inline std::string::size_type RegularExpressionMatch::start() const
+{
+ return static_cast<std::string::size_type>(this->startp[0] - searchstring);
+}
+
+/**
+ * \brief Returns the end index of the full match.
+ */
+inline std::string::size_type RegularExpressionMatch::end() const
+{
+ return static_cast<std::string::size_type>(this->endp[0] - searchstring);
+}
+
+/**
+ * \brief Returns the start index of nth submatch.
+ * start(0) is the start of the full match.
+ */
+inline std::string::size_type RegularExpressionMatch::start(int n) const
+{
+ return static_cast<std::string::size_type>(this->startp[n] -
+ this->searchstring);
+}
+
+/**
+ * \brief Returns the end index of nth submatch.
+ * end(0) is the end of the full match.
+ */
+inline std::string::size_type RegularExpressionMatch::end(int n) const
+{
+ return static_cast<std::string::size_type>(this->endp[n] -
+ this->searchstring);
+}
+
+/**
+ * \brief Returns the nth submatch as a string.
+ */
+inline std::string RegularExpressionMatch::match(int n) const
+{
+ if (this->startp[n] == 0) {
+ return std::string();
+ } else {
+ return std::string(this->startp[n], static_cast<std::string::size_type>(
+ this->endp[n] - this->startp[n]));
+ }
+}
+
/** \class RegularExpression
* \brief Implements pattern matching with regular expressions.
*
@@ -170,6 +279,9 @@ namespace @KWSYS_NAMESPACE@ {
* the same as the two characters before the first p encounterd in
* the line. It would match "drepa qrepb" in "rep drepa qrepb".
*
+ * All methods of RegularExpression can be called simultaneously from
+ * different threads but only if each invocation uses an own instance of
+ * RegularExpression.
*/
class @KWSYS_NAMESPACE@_EXPORT RegularExpression
{
@@ -213,9 +325,19 @@ public:
/**
* Matches the regular expression to the given string.
+ * Returns true if found, and sets start and end indexes
+ * in the RegularExpressionMatch instance accordingly.
+ *
+ * This method is thread safe when called with different
+ * RegularExpressionMatch instances.
+ */
+ bool find(char const*, RegularExpressionMatch&) const;
+
+ /**
+ * Matches the regular expression to the given string.
* Returns true if found, and sets start and end indexes accordingly.
*/
- bool find(char const*);
+ inline bool find(char const*);
/**
* Matches the regular expression to the given std string.
@@ -224,14 +346,18 @@ public:
inline bool find(std::string const&);
/**
- * Index to start of first find.
+ * Match indices
*/
+ inline RegularExpressionMatch const& regMatch() const;
inline std::string::size_type start() const;
+ inline std::string::size_type end() const;
+ inline std::string::size_type start(int n) const;
+ inline std::string::size_type end(int n) const;
/**
- * Index to end of first find.
+ * Match strings
*/
- inline std::string::size_type end() const;
+ inline std::string match(int n) const;
/**
* Copy the given regular expression.
@@ -266,29 +392,14 @@ public:
*/
inline void set_invalid();
- /**
- * Destructor.
- */
- // awf added
- std::string::size_type start(int n) const;
- std::string::size_type end(int n) const;
- std::string match(int n) const;
-
- enum
- {
- NSUBEXP = 10
- };
-
private:
- const char* startp[NSUBEXP];
- const char* endp[NSUBEXP];
+ RegularExpressionMatch regmatch;
char regstart; // Internal use only
char reganch; // Internal use only
const char* regmust; // Internal use only
std::string::size_type regmlen; // Internal use only
char* program;
int progsize;
- const char* searchstring;
};
/**
@@ -344,51 +455,42 @@ inline bool RegularExpression::compile(std::string const& s)
* Matches the regular expression to the given std string.
* Returns true if found, and sets start and end indexes accordingly.
*/
-inline bool RegularExpression::find(std::string const& s)
+inline bool RegularExpression::find(const char* s)
{
- return this->find(s.c_str());
+ return this->find(s, this->regmatch);
}
/**
- * Set the start position for the regular expression.
+ * Matches the regular expression to the given std string.
+ * Returns true if found, and sets start and end indexes accordingly.
*/
-inline std::string::size_type RegularExpression::start() const
+inline bool RegularExpression::find(std::string const& s)
{
- return static_cast<std::string::size_type>(this->startp[0] - searchstring);
+ return this->find(s.c_str());
}
/**
- * Returns the start/end index of the last item found.
+ * Returns the internal match object
*/
-inline std::string::size_type RegularExpression::end() const
+inline RegularExpressionMatch const& RegularExpression::regMatch() const
{
- return static_cast<std::string::size_type>(this->endp[0] - searchstring);
+ return this->regmatch;
}
/**
- * Returns true if two regular expressions have different
- * compiled program for pattern matching.
+ * Returns the start index of the full match.
*/
-inline bool RegularExpression::operator!=(const RegularExpression& r) const
+inline std::string::size_type RegularExpression::start() const
{
- return (!(*this == r));
+ return regmatch.start();
}
/**
- * Returns true if a valid regular expression is compiled
- * and ready for pattern matching.
+ * Returns the end index of the full match.
*/
-inline bool RegularExpression::is_valid() const
-{
- return (this->program != 0);
-}
-
-inline void RegularExpression::set_invalid()
+inline std::string::size_type RegularExpression::end() const
{
- //#ifndef _WIN32
- delete[] this->program;
- //#endif
- this->program = 0;
+ return regmatch.end();
}
/**
@@ -396,7 +498,7 @@ inline void RegularExpression::set_invalid()
*/
inline std::string::size_type RegularExpression::start(int n) const
{
- return static_cast<std::string::size_type>(this->startp[n] - searchstring);
+ return regmatch.start(n);
}
/**
@@ -404,7 +506,7 @@ inline std::string::size_type RegularExpression::start(int n) const
*/
inline std::string::size_type RegularExpression::end(int n) const
{
- return static_cast<std::string::size_type>(this->endp[n] - searchstring);
+ return regmatch.end(n);
}
/**
@@ -412,12 +514,33 @@ inline std::string::size_type RegularExpression::end(int n) const
*/
inline std::string RegularExpression::match(int n) const
{
- if (this->startp[n] == 0) {
- return std::string("");
- } else {
- return std::string(this->startp[n], static_cast<std::string::size_type>(
- this->endp[n] - this->startp[n]));
- }
+ return regmatch.match(n);
+}
+
+/**
+ * Returns true if two regular expressions have different
+ * compiled program for pattern matching.
+ */
+inline bool RegularExpression::operator!=(const RegularExpression& r) const
+{
+ return (!(*this == r));
+}
+
+/**
+ * Returns true if a valid regular expression is compiled
+ * and ready for pattern matching.
+ */
+inline bool RegularExpression::is_valid() const
+{
+ return (this->program != 0);
+}
+
+inline void RegularExpression::set_invalid()
+{
+ //#ifndef _WIN32
+ delete[] this->program;
+ //#endif
+ this->program = 0;
}
} // namespace @KWSYS_NAMESPACE@
diff --git a/Source/kwsys/hash_map.hxx.in b/Source/kwsys/hash_map.hxx.in
index 3f9174f..8c9b81e 100644
--- a/Source/kwsys/hash_map.hxx.in
+++ b/Source/kwsys/hash_map.hxx.in
@@ -49,7 +49,7 @@ namespace @KWSYS_NAMESPACE@ {
// select1st is an extension: it is not part of the standard.
template <class T1, class T2>
-struct hash_select1st : public std::unary_function<std::pair<T1, T2>, T1>
+struct hash_select1st
{
const T1& operator()(const std::pair<T1, T2>& __x) const
{
diff --git a/Source/kwsys/hash_set.hxx.in b/Source/kwsys/hash_set.hxx.in
index e3a0c6c..5edd367 100644
--- a/Source/kwsys/hash_set.hxx.in
+++ b/Source/kwsys/hash_set.hxx.in
@@ -49,7 +49,7 @@ namespace @KWSYS_NAMESPACE@ {
// identity is an extension: it is not part of the standard.
template <class _Tp>
-struct _Identity : public std::unary_function<_Tp, _Tp>
+struct _Identity
{
const _Tp& operator()(const _Tp& __x) const { return __x; }
};
diff --git a/Source/kwsys/hashtable.hxx.in b/Source/kwsys/hashtable.hxx.in
index dd92cb9..e962f17 100644
--- a/Source/kwsys/hashtable.hxx.in
+++ b/Source/kwsys/hashtable.hxx.in
@@ -35,13 +35,12 @@
#include <@KWSYS_NAMESPACE@/Configure.hxx>
-#include <algorithm> // lower_bound
-#include <functional> // unary_function
-#include <iterator> // iterator_traits
-#include <memory> // allocator
-#include <stddef.h> // size_t
-#include <utility> // pair
-#include <vector> // vector
+#include <algorithm> // lower_bound
+#include <iterator> // iterator_traits
+#include <memory> // allocator
+#include <stddef.h> // size_t
+#include <utility> // pair
+#include <vector> // vector
#if defined(_MSC_VER)
#pragma warning(push)
diff --git a/Source/kwsys/testConfigure.cxx b/Source/kwsys/testConfigure.cxx
new file mode 100644
index 0000000..916dcc1
--- /dev/null
+++ b/Source/kwsys/testConfigure.cxx
@@ -0,0 +1,30 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+file Copyright.txt or https://cmake.org/licensing#kwsys for details. */
+#include "kwsysPrivate.h"
+#include KWSYS_HEADER(Configure.hxx)
+
+// Work-around CMake dependency scanning limitation. This must
+// duplicate the above list of headers.
+#if 0
+#include "Configure.hxx.in"
+#endif
+
+static bool testFallthrough(int n)
+{
+ int r = 0;
+ switch (n) {
+ case 1:
+ ++r;
+ KWSYS_FALLTHROUGH;
+ default:
+ ++r;
+ }
+ return r == 2;
+}
+
+int testConfigure(int, char* [])
+{
+ bool res = true;
+ res = testFallthrough(1) && res;
+ return res ? 0 : 1;
+}