summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
Diffstat (limited to 'Source')
-rw-r--r--Source/CMakeVersion.cmake2
-rw-r--r--Source/CTest/cmCTestTestHandler.cxx82
-rw-r--r--Source/cmAddCustomCommandCommand.cxx9
-rw-r--r--Source/cmAddCustomTargetCommand.cxx13
-rw-r--r--Source/cmCustomCommand.cxx12
-rw-r--r--Source/cmCustomCommand.h5
-rw-r--r--Source/cmCustomCommandGenerator.cxx32
-rw-r--r--Source/cmCustomCommandGenerator.h2
-rw-r--r--Source/cmFileCommand.cxx2
-rw-r--r--Source/cmMakefile.cxx22
-rw-r--r--Source/cmMakefile.h15
-rw-r--r--Source/kwsys/CMakeLists.txt3
-rw-r--r--Source/kwsys/SystemTools.cxx11
-rw-r--r--Source/kwsys/testSystemTools.cxx53
14 files changed, 207 insertions, 56 deletions
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 0c64d70..d1054cf 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 7)
-set(CMake_VERSION_PATCH 20170116)
+set(CMake_VERSION_PATCH 20170117)
#set(CMake_VERSION_RC 1)
diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx
index 4e63654..6175e50 100644
--- a/Source/CTest/cmCTestTestHandler.cxx
+++ b/Source/CTest/cmCTestTestHandler.cxx
@@ -829,23 +829,31 @@ void cmCTestTestHandler::UpdateForFixtures(ListOfTests& tests) const
addedTests.insert(p.Name);
}
- // This is a lookup of fixture name to a list of indices into the
- // final tests array for tests which require that fixture. It is
- // needed at the end to populate dependencies of the cleanup tests
- // in our final list of tests.
+ // These are lookups of fixture name to a list of indices into the final
+ // tests array for tests which require that fixture and tests which are
+ // setups for that fixture. They are needed at the end to populate
+ // dependencies of the cleanup tests in our final list of tests.
std::map<std::string, std::vector<size_t> > fixtureRequirements;
+ std::map<std::string, std::vector<size_t> > setupFixturesAdded;
// Use integer index for iteration because we append to
// the tests vector as we go
size_t fixtureTestsAdded = 0;
std::set<std::string> addedFixtures;
for (size_t i = 0; i < tests.size(); ++i) {
- if (tests[i].FixturesRequired.empty()) {
- continue;
- }
- // Must copy the set of fixtures because we may invalidate
+ // There are two things to do for each test:
+ // 1. For every fixture required by this test, record that fixture as
+ // being required and create dependencies on that fixture's setup
+ // tests.
+ // 2. Record all setup tests in the final test list so we can later make
+ // cleanup tests in the test list depend on their associated setup
+ // tests to enforce correct ordering.
+
+ // 1. Handle fixture requirements
+ //
+ // Must copy the set of fixtures required because we may invalidate
// the tests array by appending to it
- const std::set<std::string> fixtures = tests[i].FixturesRequired;
+ std::set<std::string> fixtures = tests[i].FixturesRequired;
for (std::set<std::string>::const_iterator fixturesIt = fixtures.begin();
fixturesIt != fixtures.end(); ++fixturesIt) {
@@ -908,32 +916,62 @@ void cmCTestTestHandler::UpdateForFixtures(ListOfTests& tests) const
this->Quiet);
}
}
+
+ // 2. Record all setup fixtures included in the final list of tests
+ for (std::set<std::string>::const_iterator fixturesIt =
+ tests[i].FixturesSetup.begin();
+ fixturesIt != tests[i].FixturesSetup.end(); ++fixturesIt) {
+
+ const std::string& setupFixtureName = *fixturesIt;
+ if (setupFixtureName.empty()) {
+ continue;
+ }
+
+ setupFixturesAdded[setupFixtureName].push_back(i);
+ }
}
// Now that we have the final list of tests, we can update all cleanup
- // tests to depend on those tests which require that fixture
+ // tests to depend on those tests which require that fixture and on any
+ // setup tests for that fixture. The latter is required to handle the
+ // pathological case where setup and cleanup tests are in the test set
+ // but no other test has that fixture as a requirement.
for (ListOfTests::iterator tIt = tests.begin(); tIt != tests.end(); ++tIt) {
cmCTestTestProperties& p = *tIt;
const std::set<std::string>& cleanups = p.FixturesCleanup;
for (std::set<std::string>::const_iterator fIt = cleanups.begin();
fIt != cleanups.end(); ++fIt) {
const std::string& fixture = *fIt;
+
+ // This cleanup test could be part of the original test list that was
+ // passed in. It is then possible that no other test requires the
+ // fIt fixture, so we have to check for this.
std::map<std::string, std::vector<size_t> >::const_iterator cIt =
fixtureRequirements.find(fixture);
- if (cIt == fixtureRequirements.end()) {
- // No test cases require the fixture this cleanup test is for.
- // This cleanup test must have been part of the original test
- // list passed in (which is not an error)
- continue;
+ if (cIt != fixtureRequirements.end()) {
+ const std::vector<size_t>& indices = cIt->second;
+ for (std::vector<size_t>::const_iterator indexIt = indices.begin();
+ indexIt != indices.end(); ++indexIt) {
+ const std::string& reqTestName = tests[*indexIt].Name;
+ if (std::find(p.Depends.begin(), p.Depends.end(), reqTestName) ==
+ p.Depends.end()) {
+ p.Depends.push_back(reqTestName);
+ }
+ }
}
- const std::vector<size_t>& indices = cIt->second;
- for (std::vector<size_t>::const_iterator indexIt = indices.begin();
- indexIt != indices.end(); ++indexIt) {
- const std::string& reqTestName = tests[*indexIt].Name;
- if (std::find(p.Depends.begin(), p.Depends.end(), reqTestName) ==
- p.Depends.end()) {
- p.Depends.push_back(reqTestName);
+ // Ensure fixture cleanup tests always run after their setup tests, even
+ // if no other test cases require the fixture
+ cIt = setupFixturesAdded.find(fixture);
+ if (cIt != setupFixturesAdded.end()) {
+ const std::vector<size_t>& indices = cIt->second;
+ for (std::vector<size_t>::const_iterator indexIt = indices.begin();
+ indexIt != indices.end(); ++indexIt) {
+ const std::string& setupTestName = tests[*indexIt].Name;
+ if (std::find(p.Depends.begin(), p.Depends.end(), setupTestName) ==
+ p.Depends.end()) {
+ p.Depends.push_back(setupTestName);
+ }
}
}
}
diff --git a/Source/cmAddCustomCommandCommand.cxx b/Source/cmAddCustomCommandCommand.cxx
index 620de31..a100617 100644
--- a/Source/cmAddCustomCommandCommand.cxx
+++ b/Source/cmAddCustomCommandCommand.cxx
@@ -36,6 +36,7 @@ bool cmAddCustomCommandCommand::InitialPass(
bool verbatim = false;
bool append = false;
bool uses_terminal = false;
+ bool command_expand_lists = false;
std::string implicit_depends_lang;
cmCustomCommand::ImplicitDependsList implicit_depends;
@@ -92,6 +93,8 @@ bool cmAddCustomCommandCommand::InitialPass(
append = true;
} else if (copy == "USES_TERMINAL") {
uses_terminal = true;
+ } else if (copy == "COMMAND_EXPAND_LISTS") {
+ command_expand_lists = true;
} else if (copy == "TARGET") {
doing = doing_target;
} else if (copy == "ARGS") {
@@ -281,12 +284,14 @@ bool cmAddCustomCommandCommand::InitialPass(
std::vector<std::string> no_depends;
this->Makefile->AddCustomCommandToTarget(
target, byproducts, no_depends, commandLines, cctype, comment,
- working.c_str(), escapeOldStyle, uses_terminal, depfile);
+ working.c_str(), escapeOldStyle, uses_terminal, depfile,
+ command_expand_lists);
} else if (target.empty()) {
// Target is empty, use the output.
this->Makefile->AddCustomCommandToOutput(
output, byproducts, depends, main_dependency, commandLines, comment,
- working.c_str(), false, escapeOldStyle, uses_terminal, depfile);
+ working.c_str(), false, escapeOldStyle, uses_terminal,
+ command_expand_lists, depfile);
// Add implicit dependency scanning requests if any were given.
if (!implicit_depends.empty()) {
diff --git a/Source/cmAddCustomTargetCommand.cxx b/Source/cmAddCustomTargetCommand.cxx
index 56f33b4..0d01493 100644
--- a/Source/cmAddCustomTargetCommand.cxx
+++ b/Source/cmAddCustomTargetCommand.cxx
@@ -47,6 +47,7 @@ bool cmAddCustomTargetCommand::InitialPass(
std::string working_directory;
bool verbatim = false;
bool uses_terminal = false;
+ bool command_expand_lists = false;
std::string comment_buffer;
const char* comment = CM_NULLPTR;
std::vector<std::string> sources;
@@ -90,6 +91,9 @@ bool cmAddCustomTargetCommand::InitialPass(
} else if (copy == "USES_TERMINAL") {
doing = doing_nothing;
uses_terminal = true;
+ } else if (copy == "COMMAND_EXPAND_LISTS") {
+ doing = doing_nothing;
+ command_expand_lists = true;
} else if (copy == "COMMENT") {
doing = doing_comment;
} else if (copy == "COMMAND") {
@@ -221,12 +225,19 @@ bool cmAddCustomTargetCommand::InitialPass(
"USES_TERMINAL may not be specified without any COMMAND");
return true;
}
+ if (commandLines.empty() && command_expand_lists) {
+ this->Makefile->IssueMessage(
+ cmake::FATAL_ERROR,
+ "COMMAND_EXPAND_LISTS may not be specified without any COMMAND");
+ return true;
+ }
// Add the utility target to the makefile.
bool escapeOldStyle = !verbatim;
cmTarget* target = this->Makefile->AddUtilityCommand(
targetName, excludeFromAll, working_directory.c_str(), byproducts, depends,
- commandLines, escapeOldStyle, comment, uses_terminal);
+ commandLines, escapeOldStyle, comment, uses_terminal,
+ command_expand_lists);
// Add additional user-specified source files to the target.
target->AddSources(sources);
diff --git a/Source/cmCustomCommand.cxx b/Source/cmCustomCommand.cxx
index 6645b8e..050de17 100644
--- a/Source/cmCustomCommand.cxx
+++ b/Source/cmCustomCommand.cxx
@@ -13,6 +13,7 @@ cmCustomCommand::cmCustomCommand()
this->EscapeOldStyle = true;
this->EscapeAllowMakeVars = false;
this->UsesTerminal = false;
+ this->CommandExpandLists = false;
}
cmCustomCommand::cmCustomCommand(cmMakefile const* mf,
@@ -32,6 +33,7 @@ cmCustomCommand::cmCustomCommand(cmMakefile const* mf,
, HaveComment(comment != CM_NULLPTR)
, EscapeAllowMakeVars(false)
, EscapeOldStyle(true)
+ , CommandExpandLists(false)
{
if (mf) {
this->Backtrace = mf->GetBacktrace();
@@ -127,6 +129,16 @@ void cmCustomCommand::SetUsesTerminal(bool b)
this->UsesTerminal = b;
}
+bool cmCustomCommand::GetCommandExpandLists() const
+{
+ return this->CommandExpandLists;
+}
+
+void cmCustomCommand::SetCommandExpandLists(bool b)
+{
+ this->CommandExpandLists = b;
+}
+
const std::string& cmCustomCommand::GetDepfile() const
{
return this->Depfile;
diff --git a/Source/cmCustomCommand.h b/Source/cmCustomCommand.h
index 66f8fa9..73d53ff 100644
--- a/Source/cmCustomCommand.h
+++ b/Source/cmCustomCommand.h
@@ -85,6 +85,10 @@ public:
bool GetUsesTerminal() const;
void SetUsesTerminal(bool b);
+ /** Set/Get whether lists in command lines should be expanded. */
+ bool GetCommandExpandLists() const;
+ void SetCommandExpandLists(bool b);
+
/** Set/Get the depfile (used by the Ninja generator) */
const std::string& GetDepfile() const;
void SetDepfile(const std::string& depfile);
@@ -103,6 +107,7 @@ private:
bool EscapeAllowMakeVars;
bool EscapeOldStyle;
bool UsesTerminal;
+ bool CommandExpandLists;
};
#endif
diff --git a/Source/cmCustomCommandGenerator.cxx b/Source/cmCustomCommandGenerator.cxx
index 8bd3a89..8f4ff4b 100644
--- a/Source/cmCustomCommandGenerator.cxx
+++ b/Source/cmCustomCommandGenerator.cxx
@@ -26,6 +26,24 @@ cmCustomCommandGenerator::cmCustomCommandGenerator(cmCustomCommand const& cc,
, GE(new cmGeneratorExpression(cc.GetBacktrace()))
, DependsDone(false)
{
+ const cmCustomCommandLines& cmdlines = this->CC.GetCommandLines();
+ for (cmCustomCommandLines::const_iterator cmdline = cmdlines.begin();
+ cmdline != cmdlines.end(); ++cmdline) {
+ cmCustomCommandLine argv;
+ for (cmCustomCommandLine::const_iterator clarg = cmdline->begin();
+ clarg != cmdline->end(); ++clarg) {
+ CM_AUTO_PTR<cmCompiledGeneratorExpression> cge = this->GE->Parse(*clarg);
+ std::string parsed_arg = cge->Evaluate(this->LG, this->Config);
+ if (this->CC.GetCommandExpandLists()) {
+ std::vector<std::string> ExpandedArg;
+ cmSystemTools::ExpandListArgument(parsed_arg, ExpandedArg);
+ argv.insert(argv.end(), ExpandedArg.begin(), ExpandedArg.end());
+ } else {
+ argv.push_back(parsed_arg);
+ }
+ }
+ this->CommandLines.push_back(argv);
+ }
}
cmCustomCommandGenerator::~cmCustomCommandGenerator()
@@ -44,7 +62,7 @@ const char* cmCustomCommandGenerator::GetCrossCompilingEmulator(
if (!this->LG->GetMakefile()->IsOn("CMAKE_CROSSCOMPILING")) {
return CM_NULLPTR;
}
- std::string const& argv0 = this->CC.GetCommandLines()[c][0];
+ std::string const& argv0 = this->CommandLines[c][0];
cmGeneratorTarget* target = this->LG->FindGeneratorTargetToUse(argv0);
if (target && target->GetType() == cmStateEnums::EXECUTABLE &&
!target->IsImported()) {
@@ -55,7 +73,7 @@ const char* cmCustomCommandGenerator::GetCrossCompilingEmulator(
const char* cmCustomCommandGenerator::GetArgv0Location(unsigned int c) const
{
- std::string const& argv0 = this->CC.GetCommandLines()[c][0];
+ std::string const& argv0 = this->CommandLines[c][0];
cmGeneratorTarget* target = this->LG->FindGeneratorTargetToUse(argv0);
if (target && target->GetType() == cmStateEnums::EXECUTABLE &&
(target->IsImported() ||
@@ -75,11 +93,7 @@ std::string cmCustomCommandGenerator::GetCommand(unsigned int c) const
return std::string(location);
}
- std::string const& argv0 = this->CC.GetCommandLines()[c][0];
- CM_AUTO_PTR<cmCompiledGeneratorExpression> cge = this->GE->Parse(argv0);
- std::string exe = cge->Evaluate(this->LG, this->Config);
-
- return exe;
+ return this->CommandLines[c][0];
}
std::string escapeForShellOldStyle(const std::string& str)
@@ -114,7 +128,7 @@ void cmCustomCommandGenerator::AppendArguments(unsigned int c,
if (this->GetCrossCompilingEmulator(c) != CM_NULLPTR) {
offset = 0;
}
- cmCustomCommandLine const& commandLine = this->CC.GetCommandLines()[c];
+ cmCustomCommandLine const& commandLine = this->CommandLines[c];
for (unsigned int j = offset; j < commandLine.size(); ++j) {
std::string arg;
if (const char* location =
@@ -123,7 +137,7 @@ void cmCustomCommandGenerator::AppendArguments(unsigned int c,
// so transform the latter now.
arg = location;
} else {
- arg = this->GE->Parse(commandLine[j])->Evaluate(this->LG, this->Config);
+ arg = commandLine[j];
}
cmd += " ";
if (this->OldStyle) {
diff --git a/Source/cmCustomCommandGenerator.h b/Source/cmCustomCommandGenerator.h
index 8983c54..286aaf3 100644
--- a/Source/cmCustomCommandGenerator.h
+++ b/Source/cmCustomCommandGenerator.h
@@ -3,6 +3,7 @@
#ifndef cmCustomCommandGenerator_h
#define cmCustomCommandGenerator_h
+#include "cmCustomCommandLines.h"
#include <cmConfigure.h> // IWYU pragma: keep
#include <string>
@@ -22,6 +23,7 @@ class cmCustomCommandGenerator
cmGeneratorExpression* GE;
mutable bool DependsDone;
mutable std::vector<std::string> Depends;
+ cmCustomCommandLines CommandLines;
const char* GetCrossCompilingEmulator(unsigned int c) const;
const char* GetArgv0Location(unsigned int c) const;
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx
index d10c886..91cecb3 100644
--- a/Source/cmFileCommand.cxx
+++ b/Source/cmFileCommand.cxx
@@ -788,7 +788,7 @@ bool cmFileCommand::HandleGlobCommand(std::vector<std::string> const& args,
this->SetError("LIST_DIRECTORIES missing bool value.");
return false;
}
- ++i;
+ continue;
}
if (recurse && (*i == "FOLLOW_SYMLINKS")) {
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index cfc0495..bfe46ae 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -692,7 +692,7 @@ void cmMakefile::AddCustomCommandToTarget(
const std::vector<std::string>& depends,
const cmCustomCommandLines& commandLines, cmTarget::CustomCommandType type,
const char* comment, const char* workingDir, bool escapeOldStyle,
- bool uses_terminal, const std::string& depfile)
+ bool uses_terminal, const std::string& depfile, bool command_expand_lists)
{
// Find the target to which to add the custom command.
cmTargets::iterator ti = this->Targets.find(target);
@@ -764,6 +764,7 @@ void cmMakefile::AddCustomCommandToTarget(
cc.SetEscapeOldStyle(escapeOldStyle);
cc.SetEscapeAllowMakeVars(true);
cc.SetUsesTerminal(uses_terminal);
+ cc.SetCommandExpandLists(command_expand_lists);
cc.SetDepfile(depfile);
switch (type) {
case cmTarget::PRE_BUILD:
@@ -784,7 +785,7 @@ cmSourceFile* cmMakefile::AddCustomCommandToOutput(
const std::vector<std::string>& depends, const std::string& main_dependency,
const cmCustomCommandLines& commandLines, const char* comment,
const char* workingDir, bool replace, bool escapeOldStyle,
- bool uses_terminal, const std::string& depfile)
+ bool uses_terminal, bool command_expand_lists, const std::string& depfile)
{
// Make sure there is at least one output.
if (outputs.empty()) {
@@ -878,6 +879,7 @@ cmSourceFile* cmMakefile::AddCustomCommandToOutput(
cc->SetEscapeOldStyle(escapeOldStyle);
cc->SetEscapeAllowMakeVars(true);
cc->SetUsesTerminal(uses_terminal);
+ cc->SetCommandExpandLists(command_expand_lists);
cc->SetDepfile(depfile);
file->SetCustomCommand(cc);
this->UpdateOutputToSourceMap(outputs, file);
@@ -916,14 +918,16 @@ cmSourceFile* cmMakefile::AddCustomCommandToOutput(
const std::string& output, const std::vector<std::string>& depends,
const std::string& main_dependency, const cmCustomCommandLines& commandLines,
const char* comment, const char* workingDir, bool replace,
- bool escapeOldStyle, bool uses_terminal, const std::string& depfile)
+ bool escapeOldStyle, bool uses_terminal, bool command_expand_lists,
+ const std::string& depfile)
{
std::vector<std::string> outputs;
outputs.push_back(output);
std::vector<std::string> no_byproducts;
return this->AddCustomCommandToOutput(
outputs, no_byproducts, depends, main_dependency, commandLines, comment,
- workingDir, replace, escapeOldStyle, uses_terminal, depfile);
+ workingDir, replace, escapeOldStyle, uses_terminal, command_expand_lists,
+ depfile);
}
void cmMakefile::AddCustomCommandOldStyle(
@@ -1018,12 +1022,13 @@ cmTarget* cmMakefile::AddUtilityCommand(
const std::string& utilityName, bool excludeFromAll,
const char* workingDirectory, const std::vector<std::string>& depends,
const cmCustomCommandLines& commandLines, bool escapeOldStyle,
- const char* comment, bool uses_terminal)
+ const char* comment, bool uses_terminal, bool command_expand_lists)
{
std::vector<std::string> no_byproducts;
return this->AddUtilityCommand(utilityName, excludeFromAll, workingDirectory,
no_byproducts, depends, commandLines,
- escapeOldStyle, comment, uses_terminal);
+ escapeOldStyle, comment, uses_terminal,
+ command_expand_lists);
}
cmTarget* cmMakefile::AddUtilityCommand(
@@ -1031,7 +1036,7 @@ cmTarget* cmMakefile::AddUtilityCommand(
const char* workingDirectory, const std::vector<std::string>& byproducts,
const std::vector<std::string>& depends,
const cmCustomCommandLines& commandLines, bool escapeOldStyle,
- const char* comment, bool uses_terminal)
+ const char* comment, bool uses_terminal, bool command_expand_lists)
{
// Create a target instance for this utility.
cmTarget* target = this->AddNewTarget(cmStateEnums::UTILITY, utilityName);
@@ -1055,7 +1060,8 @@ cmTarget* cmMakefile::AddUtilityCommand(
bool no_replace = false;
this->AddCustomCommandToOutput(
forced, byproducts, depends, no_main_dependency, commandLines, comment,
- workingDirectory, no_replace, escapeOldStyle, uses_terminal);
+ workingDirectory, no_replace, escapeOldStyle, uses_terminal,
+ command_expand_lists);
cmSourceFile* sf = target->AddSourceCMP0049(force);
// The output is not actually created so mark it symbolic.
diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h
index 3484e5a..9d9e90a 100644
--- a/Source/cmMakefile.h
+++ b/Source/cmMakefile.h
@@ -125,7 +125,8 @@ public:
const std::vector<std::string>& depends,
const cmCustomCommandLines& commandLines, cmTarget::CustomCommandType type,
const char* comment, const char* workingDir, bool escapeOldStyle = true,
- bool uses_terminal = false, const std::string& depfile = "");
+ bool uses_terminal = false, const std::string& depfile = "",
+ bool command_expand_lists = false);
cmSourceFile* AddCustomCommandToOutput(
const std::vector<std::string>& outputs,
const std::vector<std::string>& byproducts,
@@ -133,13 +134,15 @@ public:
const std::string& main_dependency,
const cmCustomCommandLines& commandLines, const char* comment,
const char* workingDir, bool replace = false, bool escapeOldStyle = true,
- bool uses_terminal = false, const std::string& depfile = "");
+ bool uses_terminal = false, bool command_expand_lists = false,
+ const std::string& depfile = "");
cmSourceFile* AddCustomCommandToOutput(
const std::string& output, const std::vector<std::string>& depends,
const std::string& main_dependency,
const cmCustomCommandLines& commandLines, const char* comment,
const char* workingDir, bool replace = false, bool escapeOldStyle = true,
- bool uses_terminal = false, const std::string& depfile = "");
+ bool uses_terminal = false, bool command_expand_lists = false,
+ const std::string& depfile = "");
void AddCustomCommandOldStyle(const std::string& target,
const std::vector<std::string>& outputs,
const std::vector<std::string>& depends,
@@ -182,13 +185,15 @@ public:
const std::string& utilityName, bool excludeFromAll,
const char* workingDirectory, const std::vector<std::string>& depends,
const cmCustomCommandLines& commandLines, bool escapeOldStyle = true,
- const char* comment = CM_NULLPTR, bool uses_terminal = false);
+ const char* comment = CM_NULLPTR, bool uses_terminal = false,
+ bool command_expand_lists = false);
cmTarget* AddUtilityCommand(
const std::string& utilityName, bool excludeFromAll,
const char* workingDirectory, const std::vector<std::string>& byproducts,
const std::vector<std::string>& depends,
const cmCustomCommandLines& commandLines, bool escapeOldStyle = true,
- const char* comment = CM_NULLPTR, bool uses_terminal = false);
+ const char* comment = CM_NULLPTR, bool uses_terminal = false,
+ bool command_expand_lists = false);
/**
* Add a subdirectory to the build.
diff --git a/Source/kwsys/CMakeLists.txt b/Source/kwsys/CMakeLists.txt
index 9eb3b2d..d4fe8a7 100644
--- a/Source/kwsys/CMakeLists.txt
+++ b/Source/kwsys/CMakeLists.txt
@@ -818,6 +818,9 @@ IF(KWSYS_C_SRCS OR KWSYS_CXX_SRCS)
# for symbol lookup using dladdr
TARGET_LINK_LIBRARIES(${KWSYS_NAMESPACE} ${CMAKE_DL_LIBS})
ENDIF()
+ IF (CMAKE_SYSTEM_NAME STREQUAL "SunOS")
+ TARGET_LINK_LIBRARIES(${KWSYS_NAMESPACE} socket)
+ ENDIF()
ENDIF()
ENDIF()
diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx
index b018a43..97dd4ae 100644
--- a/Source/kwsys/SystemTools.cxx
+++ b/Source/kwsys/SystemTools.cxx
@@ -763,7 +763,7 @@ bool SystemTools::MakeDirectory(const char* path)
bool SystemTools::MakeDirectory(const std::string& path)
{
- if (SystemTools::FileExists(path)) {
+ if (SystemTools::PathExists(path)) {
return SystemTools::FileIsDirectory(path);
}
if (path.empty()) {
@@ -1280,7 +1280,7 @@ bool SystemTools::PathCygwinToWin32(const char* path, char* win32_path)
bool SystemTools::Touch(const std::string& filename, bool create)
{
- if (!SystemTools::FileExists(filename)) {
+ if (!SystemTools::PathExists(filename)) {
if (create) {
FILE* file = Fopen(filename, "a+b");
if (file) {
@@ -4289,7 +4289,7 @@ bool SystemTools::GetLineFromStream(std::istream& is, std::string& line,
// if we read too much then truncate the buffer
if (leftToRead > 0) {
if (static_cast<long>(length) > leftToRead) {
- buffer[leftToRead - 1] = 0;
+ buffer[leftToRead] = 0;
leftToRead = 0;
} else {
leftToRead -= static_cast<long>(length);
@@ -4389,10 +4389,7 @@ bool SystemTools::SetPermissions(const char* file, mode_t mode,
bool SystemTools::SetPermissions(const std::string& file, mode_t mode,
bool honor_umask)
{
- // TEMPORARY / TODO: After FileExists calls lstat() instead of
- // access(), change this call to FileExists instead of
- // TestFileAccess so that we don't follow symlinks.
- if (!SystemTools::TestFileAccess(file, TEST_FILE_OK)) {
+ if (!SystemTools::PathExists(file)) {
return false;
}
if (honor_umask) {
diff --git a/Source/kwsys/testSystemTools.cxx b/Source/kwsys/testSystemTools.cxx
index b04f2cb..8e1ea25 100644
--- a/Source/kwsys/testSystemTools.cxx
+++ b/Source/kwsys/testSystemTools.cxx
@@ -6,11 +6,13 @@
#pragma warning(disable : 4786)
#endif
+#include KWSYS_HEADER(FStream.hxx)
#include KWSYS_HEADER(SystemTools.hxx)
// Work-around CMake dependency scanning limitation. This must
// duplicate the above list of headers.
#if 0
+#include "FStream.hxx.in"
#include "SystemTools.hxx.in"
#endif
@@ -857,6 +859,55 @@ static bool CheckFind()
return res;
}
+static bool CheckGetLineFromStream()
+{
+ const std::string fileWithFiveCharsOnFirstLine(TEST_SYSTEMTOOLS_SOURCE_DIR
+ "/README.rst");
+
+ kwsys::ifstream file(fileWithFiveCharsOnFirstLine.c_str(), std::ios::in);
+
+ if (!file) {
+ std::cerr << "Problem opening: " << fileWithFiveCharsOnFirstLine
+ << std::endl;
+ return false;
+ }
+
+ std::string line;
+ bool has_newline = false;
+ bool result;
+
+ file.seekg(0, std::ios::beg);
+ result = kwsys::SystemTools::GetLineFromStream(file, line, &has_newline, -1);
+ if (!result || line.size() != 5) {
+ std::cerr << "First line does not have five characters: " << line.size()
+ << std::endl;
+ return false;
+ }
+
+ file.seekg(0, std::ios::beg);
+ result = kwsys::SystemTools::GetLineFromStream(file, line, &has_newline, -1);
+ if (!result || line.size() != 5) {
+ std::cerr << "First line does not have five characters after rewind: "
+ << line.size() << std::endl;
+ return false;
+ }
+
+ bool ret = true;
+
+ for (size_t size = 1; size <= 5; ++size) {
+ file.seekg(0, std::ios::beg);
+ result = kwsys::SystemTools::GetLineFromStream(file, line, &has_newline,
+ static_cast<long>(size));
+ if (!result || line.size() != size) {
+ std::cerr << "Should have read " << size << " characters but got "
+ << line.size() << std::endl;
+ ret = false;
+ }
+ }
+
+ return ret;
+}
+
//----------------------------------------------------------------------------
int testSystemTools(int, char* [])
{
@@ -893,5 +944,7 @@ int testSystemTools(int, char* [])
res &= CheckFind();
+ res &= CheckGetLineFromStream();
+
return res ? 0 : 1;
}