diff options
Diffstat (limited to 'Source')
-rw-r--r-- | Source/CMakeVersion.cmake | 2 | ||||
-rw-r--r-- | Source/CTest/cmCTestTestHandler.cxx | 82 | ||||
-rw-r--r-- | Source/cmAddCustomCommandCommand.cxx | 9 | ||||
-rw-r--r-- | Source/cmAddCustomTargetCommand.cxx | 13 | ||||
-rw-r--r-- | Source/cmCustomCommand.cxx | 12 | ||||
-rw-r--r-- | Source/cmCustomCommand.h | 5 | ||||
-rw-r--r-- | Source/cmCustomCommandGenerator.cxx | 32 | ||||
-rw-r--r-- | Source/cmCustomCommandGenerator.h | 2 | ||||
-rw-r--r-- | Source/cmFileCommand.cxx | 2 | ||||
-rw-r--r-- | Source/cmMakefile.cxx | 22 | ||||
-rw-r--r-- | Source/cmMakefile.h | 15 | ||||
-rw-r--r-- | Source/kwsys/CMakeLists.txt | 3 | ||||
-rw-r--r-- | Source/kwsys/SystemTools.cxx | 11 | ||||
-rw-r--r-- | Source/kwsys/testSystemTools.cxx | 53 |
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; } |