summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
Diffstat (limited to 'Source')
-rw-r--r--Source/CMakeVersion.cmake2
-rw-r--r--Source/cmFileCommand.cxx8
-rw-r--r--Source/cmMakefileLibraryTargetGenerator.cxx13
-rw-r--r--Source/kwsys/SystemTools.cxx52
-rw-r--r--Source/kwsys/SystemTools.hxx.in5
-rw-r--r--Source/kwsys/testDirectory.cxx33
-rw-r--r--Source/kwsys/testSystemTools.cxx74
7 files changed, 139 insertions, 48 deletions
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 6f9e5f0..c6ab633 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 11)
-set(CMake_VERSION_PATCH 20180516)
+set(CMake_VERSION_PATCH 20180521)
#set(CMake_VERSION_RC 1)
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx
index 6c1a869..1e47687 100644
--- a/Source/cmFileCommand.cxx
+++ b/Source/cmFileCommand.cxx
@@ -232,6 +232,14 @@ bool cmFileCommand::HandleWriteCommand(std::vector<std::string> const& args,
}
std::string message = cmJoin(cmMakeRange(i, args.end()), std::string());
file << message;
+ if (!file) {
+ std::string error = "write failed (";
+ error += cmSystemTools::GetLastSystemError();
+ error += "):\n ";
+ error += fileName;
+ this->SetError(error);
+ return false;
+ }
file.close();
if (mode) {
cmSystemTools::SetPermissions(fileName.c_str(), mode);
diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx
index 27fae04..c538992 100644
--- a/Source/cmMakefileLibraryTargetGenerator.cxx
+++ b/Source/cmMakefileLibraryTargetGenerator.cxx
@@ -5,6 +5,7 @@
#include <algorithm>
#include <memory> // IWYU pragma: keep
#include <sstream>
+#include <stddef.h>
#include <vector>
#include "cmGeneratedFileStream.h"
@@ -732,10 +733,14 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
// Archiving rules never use a response file.
useResponseFileForObjects = false;
- // Limit the length of individual object lists to less than the
- // 32K command line length limit on Windows. We could make this a
- // platform file variable but this should work everywhere.
- archiveCommandLimit = 30000;
+ // Limit the length of individual object lists to less than half of
+ // the command line length limit (leaving half for other flags).
+ // This may result in several calls to the archiver.
+ if (size_t limit = cmSystemTools::CalculateCommandLineLengthLimit()) {
+ archiveCommandLimit = limit / 2;
+ } else {
+ archiveCommandLimit = 8000;
+ }
}
// Expand the rule variables.
diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx
index 52f509a..7743e4e 100644
--- a/Source/kwsys/SystemTools.cxx
+++ b/Source/kwsys/SystemTools.cxx
@@ -2282,7 +2282,9 @@ bool SystemTools::CopyADirectory(const std::string& source,
const std::string& destination, bool always)
{
Directory dir;
- dir.Load(source);
+ if (dir.Load(source) == 0) {
+ return false;
+ }
size_t fileNum;
if (!SystemTools::MakeDirectory(destination)) {
return false;
@@ -4030,23 +4032,16 @@ std::string SystemTools::MakeCidentifier(const std::string& s)
return str;
}
-// Due to a buggy stream library on the HP and another on Mac OS X, we
-// need this very carefully written version of getline. Returns true
+// Convenience function around std::getline which removes a trailing carriage
+// return and can truncate the buffer as needed. Returns true
// if any data were read before the end-of-file was reached.
bool SystemTools::GetLineFromStream(std::istream& is, std::string& line,
bool* has_newline /* = 0 */,
long sizeLimit /* = -1 */)
{
- const int bufferSize = 1024;
- char buffer[bufferSize];
- bool haveData = false;
- bool haveNewline = false;
-
// Start with an empty line.
line = "";
- long leftToRead = sizeLimit;
-
// Early short circuit return if stream is no good. Just return
// false and the empty line. (Probably means caller tried to
// create a file stream with a non-existent file name...)
@@ -4058,44 +4053,23 @@ bool SystemTools::GetLineFromStream(std::istream& is, std::string& line,
return false;
}
- // If no characters are read from the stream, the end of file has
- // been reached. Clear the fail bit just before reading.
- while (!haveNewline && leftToRead != 0 &&
- (static_cast<void>(is.clear(is.rdstate() & ~std::ios::failbit)),
- static_cast<void>(is.getline(buffer, bufferSize)),
- is.gcount() > 0)) {
- // We have read at least one byte.
- haveData = true;
-
- // If newline character was read the gcount includes the character
- // but the buffer does not: the end of line has been reached.
- size_t length = strlen(buffer);
- if (length < static_cast<size_t>(is.gcount())) {
- haveNewline = true;
- }
-
+ std::getline(is, line);
+ bool haveData = !line.empty() || !is.eof();
+ if (!line.empty()) {
// Avoid storing a carriage return character.
- if (length > 0 && buffer[length - 1] == '\r') {
- buffer[length - 1] = 0;
+ if (*line.rbegin() == '\r') {
+ line.resize(line.size() - 1);
}
// if we read too much then truncate the buffer
- if (leftToRead > 0) {
- if (static_cast<long>(length) > leftToRead) {
- buffer[leftToRead] = 0;
- leftToRead = 0;
- } else {
- leftToRead -= static_cast<long>(length);
- }
+ if (sizeLimit >= 0 && line.size() >= static_cast<size_t>(sizeLimit)) {
+ line.resize(sizeLimit);
}
-
- // Append the data read to the line.
- line.append(buffer);
}
// Return the results.
if (has_newline) {
- *has_newline = haveNewline;
+ *has_newline = !is.eof();
}
return haveData;
}
diff --git a/Source/kwsys/SystemTools.hxx.in b/Source/kwsys/SystemTools.hxx.in
index e79e3fc..3898e3a 100644
--- a/Source/kwsys/SystemTools.hxx.in
+++ b/Source/kwsys/SystemTools.hxx.in
@@ -523,9 +523,8 @@ public:
static bool GetShortPath(const std::string& path, std::string& result);
/**
- * Read line from file. Make sure to get everything. Due to a buggy stream
- * library on the HP and another on Mac OS X, we need this very carefully
- * written version of getline. Returns true if any data were read before the
+ * Read line from file. Make sure to read a full line and truncates it if
+ * requested via sizeLimit. Returns true if any data were read before the
* end-of-file was reached. If the has_newline argument is specified, it will
* be true when the line read had a newline character.
*/
diff --git a/Source/kwsys/testDirectory.cxx b/Source/kwsys/testDirectory.cxx
index 983f2c6..62a0986 100644
--- a/Source/kwsys/testDirectory.cxx
+++ b/Source/kwsys/testDirectory.cxx
@@ -73,7 +73,38 @@ int _doLongPathTest()
return res;
}
+int _copyDirectoryTest()
+{
+ using namespace kwsys;
+ const std::string source(TEST_SYSTEMTOOLS_BINARY_DIR
+ "/directory_testing/copyDirectoryTestSrc");
+ if (SystemTools::PathExists(source)) {
+ std::cerr << source << " shouldn't exist before test" << std::endl;
+ return 1;
+ }
+ const std::string destination(TEST_SYSTEMTOOLS_BINARY_DIR
+ "/directory_testing/copyDirectoryTestDst");
+ if (SystemTools::PathExists(destination)) {
+ std::cerr << destination << " shouldn't exist before test" << std::endl;
+ return 2;
+ }
+ const bool copysuccess = SystemTools::CopyADirectory(source, destination);
+ const bool destinationexists = SystemTools::PathExists(destination);
+ if (copysuccess) {
+ std::cerr << "CopyADirectory should have returned false" << std::endl;
+ SystemTools::RemoveADirectory(destination);
+ return 3;
+ }
+ if (destinationexists) {
+ std::cerr << "CopyADirectory returned false, but destination directory"
+ << " has been created" << std::endl;
+ SystemTools::RemoveADirectory(destination);
+ return 4;
+ }
+ return 0;
+}
+
int testDirectory(int, char* [])
{
- return _doLongPathTest();
+ return _doLongPathTest() + _copyDirectoryTest();
}
diff --git a/Source/kwsys/testSystemTools.cxx b/Source/kwsys/testSystemTools.cxx
index a6d934b..8c928d4 100644
--- a/Source/kwsys/testSystemTools.cxx
+++ b/Source/kwsys/testSystemTools.cxx
@@ -912,6 +912,78 @@ static bool CheckGetLineFromStream()
return ret;
}
+static bool CheckGetLineFromStreamLongLine()
+{
+ const std::string fileWithLongLine("longlines.txt");
+ std::string firstLine, secondLine;
+ // First line: large buffer, containing a carriage return for some reason.
+ firstLine.assign(2050, ' ');
+ firstLine += "\rfirst";
+ secondLine.assign(2050, 'y');
+ secondLine += "second";
+
+ // Create file with long lines.
+ {
+ kwsys::ofstream out(fileWithLongLine.c_str(), std::ios::binary);
+ if (!out) {
+ std::cerr << "Problem opening for write: " << fileWithLongLine
+ << std::endl;
+ return false;
+ }
+ out << firstLine << "\r\n\n" << secondLine << "\n";
+ }
+
+ kwsys::ifstream file(fileWithLongLine.c_str(), std::ios::binary);
+ if (!file) {
+ std::cerr << "Problem opening: " << fileWithLongLine << std::endl;
+ return false;
+ }
+
+ std::string line;
+ bool has_newline = false;
+ bool result;
+
+ // Read first line.
+ result = kwsys::SystemTools::GetLineFromStream(file, line, &has_newline, -1);
+ if (!result || line != firstLine) {
+ std::cerr << "First line does not match, expected " << firstLine.size()
+ << " characters, got " << line.size() << std::endl;
+ return false;
+ }
+ if (!has_newline) {
+ std::cerr << "Expected new line to be read from first line" << std::endl;
+ return false;
+ }
+
+ // Read empty line.
+ has_newline = false;
+ result = kwsys::SystemTools::GetLineFromStream(file, line, &has_newline, -1);
+ if (!result || !line.empty()) {
+ std::cerr << "Expected successful read with an empty line, got "
+ << line.size() << " characters" << std::endl;
+ return false;
+ }
+ if (!has_newline) {
+ std::cerr << "Expected new line to be read for an empty line" << std::endl;
+ return false;
+ }
+
+ // Read second line.
+ has_newline = false;
+ result = kwsys::SystemTools::GetLineFromStream(file, line, &has_newline, -1);
+ if (!result || line != secondLine) {
+ std::cerr << "Second line does not match, expected " << secondLine.size()
+ << " characters, got " << line.size() << std::endl;
+ return false;
+ }
+ if (!has_newline) {
+ std::cerr << "Expected new line to be read from second line" << std::endl;
+ return false;
+ }
+
+ return true;
+}
+
int testSystemTools(int, char* [])
{
bool res = true;
@@ -951,6 +1023,8 @@ int testSystemTools(int, char* [])
res &= CheckGetLineFromStream();
+ res &= CheckGetLineFromStreamLongLine();
+
res &= CheckGetFilenameName();
return res ? 0 : 1;