Commit 9bbfa77c authored by Kitware Robot's avatar Kitware Robot Committed by Brad King
Browse files

KWSys 2015-08-24 (cdaf522c)

Extract upstream KWSys using the following shell commands.

$ git archive --prefix=upstream-kwsys/ cdaf522c | tar x
$ git shortlog --no-merges --abbrev=8 --format='%h %s' f63febb7..cdaf522c
Brad King (2):
      c8e5d1b2 Pass C++ standard flags to SunPro in standalone build
      91cb7820 Remove unused source file "CMakeEmptyInputFile.in"

James Johnston (7):
      dad68c33 Encoding: Fix undefined behavior if out of memory.
      0bca555e Process: Test running a process many times to discover resource leaks
      52788bb8 SystemTools:  Remove trailing whitespace.
      8122214c cmake: Set CMAKE_LEGACY_CYGWIN_WIN32 to 0.
      389d416b SystemTools:  Clarify/simplify behavior of FileExists
      8970cd56 SystemTools:  Added new TestFileAccess function.
      cdaf522c SystemTools:  Add honor_umask parameter to SetPermissions.

Jean-Christophe Fillion-Robin (2):
      e5c23738 SystemTools: Fix DetectFileType failure on missing file
      6d83c113 SystemTools: Fix DetectFileType failure on directory

Mattias Ellert (1):
      b9df3e48 Fix implementation of KWSYS_PROPERTIES_C

Sebastian Schuberth (1):
      4db8e69f SystemTools: Implement FileIsSymlink on Windows
parent 49efb6ae
@CMAKE_EMPTY_INPUT_FILE_CONTENT@
......@@ -91,6 +91,7 @@ ENDIF()
IF(POLICY CMP0056)
CMAKE_POLICY(SET CMP0056 NEW)
ENDIF()
SET(CMAKE_LEGACY_CYGWIN_WIN32 0)
#-----------------------------------------------------------------------------
# If a namespace is not specified, use "kwsys" and enable testing.
......@@ -311,6 +312,15 @@ IF(NOT CMAKE_COMPILER_IS_GNUCXX)
ENDIF()
ENDIF()
ENDIF()
IF(KWSYS_STANDALONE)
IF(CMAKE_CXX_COMPILER_ID STREQUAL SunPro)
IF(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.13)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++03")
ELSE()
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -library=stlport4")
ENDIF()
ENDIF()
ENDIF()
#-----------------------------------------------------------------------------
# Configure Large File Support.
......@@ -1071,7 +1081,7 @@ IF(KWSYS_ENABLE_C AND KWSYS_C_SRCS)
# Apply user-defined target properties to the library.
IF(KWSYS_PROPERTIES_C)
SET_TARGET_PROPERTIES(${KWSYS_NAMESPACE} PROPERTIES
SET_TARGET_PROPERTIES(${KWSYS_NAMESPACE}_c PROPERTIES
${KWSYS_PROPERTIES_C}
)
ENDIF()
......
......@@ -45,8 +45,11 @@ wchar_t* kwsysEncoding_DupToWide(const char* str)
if(length > 0)
{
ret = (wchar_t*)malloc((length)*sizeof(wchar_t));
ret[0] = 0;
kwsysEncoding_mbstowcs(ret, str, length);
if(ret)
{
ret[0] = 0;
kwsysEncoding_mbstowcs(ret, str, length);
}
}
return ret;
}
......@@ -72,8 +75,11 @@ char* kwsysEncoding_DupToNarrow(const wchar_t* str)
if(length > 0)
{
ret = (char*)malloc(length);
ret[0] = 0;
kwsysEncoding_wcstombs(ret, str, length);
if(ret)
{
ret[0] = 0;
kwsysEncoding_wcstombs(ret, str, length);
}
}
return ret;
}
......@@ -68,6 +68,10 @@
#include <sys/stat.h>
#include <time.h>
#ifdef _MSC_VER
# define umask _umask // Note this is still umask on Borland
#endif
// support for realpath call
#ifndef _WIN32
#include <sys/time.h>
......@@ -1233,13 +1237,11 @@ bool SystemTools::FileExists(const kwsys_stl::string& filename)
//----------------------------------------------------------------------------
bool SystemTools::FileExists(const char* filename, bool isFile)
{
if(SystemTools::FileExists(filename))
if(!filename)
{
// If isFile is set return not FileIsDirectory,
// so this will only be true if it is a file
return !isFile || !SystemTools::FileIsDirectory(filename);
return false;
}
return false;
return SystemTools::FileExists(kwsys_stl::string(filename), isFile);
}
//----------------------------------------------------------------------------
......@@ -1254,6 +1256,43 @@ bool SystemTools::FileExists(const kwsys_stl::string& filename, bool isFile)
return false;
}
//----------------------------------------------------------------------------
bool SystemTools::TestFileAccess(const char* filename,
TestFilePermissions permissions)
{
if(!filename)
{
return false;
}
return SystemTools::TestFileAccess(kwsys_stl::string(filename),
permissions);
}
//----------------------------------------------------------------------------
bool SystemTools::TestFileAccess(const kwsys_stl::string& filename,
TestFilePermissions permissions)
{
if(filename.empty())
{
return false;
}
#if defined(_WIN32) && !defined(__CYGWIN__)
// If execute set, change to read permission (all files on Windows
// are executable if they are readable). The CRT will always fail
// if you pass an execute bit.
if(permissions & TEST_FILE_EXECUTE)
{
permissions &= ~TEST_FILE_EXECUTE;
permissions |= TEST_FILE_READ;
}
return _waccess(
SystemTools::ConvertToWindowsExtendedPath(filename).c_str(),
permissions) == 0;
#else
return access(filename.c_str(), permissions) == 0;
#endif
}
//----------------------------------------------------------------------------
#ifdef __CYGWIN__
bool SystemTools::PathCygwinToWin32(const char *path, char *win32_path)
......@@ -3198,8 +3237,16 @@ bool SystemTools::FileIsDirectory(const kwsys_stl::string& inName)
bool SystemTools::FileIsSymlink(const kwsys_stl::string& name)
{
#if defined( _WIN32 )
(void)name;
return false;
DWORD attr = GetFileAttributesW(
SystemTools::ConvertToWindowsExtendedPath(name).c_str());
if (attr != INVALID_FILE_ATTRIBUTES)
{
return (attr & FILE_ATTRIBUTE_REPARSE_POINT) != 0;
}
else
{
return false;
}
#else
struct stat fs;
if(lstat(name.c_str(), &fs) == 0)
......@@ -4230,6 +4277,11 @@ SystemTools::DetectFileType(const char *filename,
return SystemTools::FileTypeUnknown;
}
if (SystemTools::FileIsDirectory(filename))
{
return SystemTools::FileTypeUnknown;
}
FILE *fp = Fopen(filename, "rb");
if (!fp)
{
......@@ -4243,6 +4295,7 @@ SystemTools::DetectFileType(const char *filename,
fclose(fp);
if (read_length == 0)
{
delete [] buffer;
return SystemTools::FileTypeUnknown;
}
......@@ -4731,21 +4784,35 @@ bool SystemTools::GetPermissions(const kwsys_stl::string& file, mode_t& mode)
return true;
}
bool SystemTools::SetPermissions(const char* file, mode_t mode)
bool SystemTools::SetPermissions(const char* file,
mode_t mode,
bool honor_umask)
{
if ( !file )
{
return false;
}
return SystemTools::SetPermissions(kwsys_stl::string(file), mode);
return SystemTools::SetPermissions(
kwsys_stl::string(file), mode, honor_umask);
}
bool SystemTools::SetPermissions(const kwsys_stl::string& file, mode_t mode)
bool SystemTools::SetPermissions(const kwsys_stl::string& file,
mode_t mode,
bool honor_umask)
{
if ( !SystemTools::FileExists(file) )
// 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) )
{
return false;
}
if (honor_umask)
{
mode_t currentMask = umask(0);
umask(currentMask);
mode &= ~currentMask;
}
#ifdef _WIN32
if ( _wchmod(SystemTools::ConvertToWindowsExtendedPath(file).c_str(),
mode) < 0 )
......
......@@ -21,6 +21,9 @@
#include <@KWSYS_NAMESPACE@/String.hxx>
#include <sys/types.h>
#if !defined(_WIN32) || defined(__CYGWIN__)
# include <unistd.h> // For access permissions for use with access()
#endif
// Required for va_list
#include <stdarg.h>
......@@ -68,10 +71,28 @@ public:
};
// This instance will show up in any translation unit that uses
// SystemTools. It will make sure SystemTools is initialized
// SystemTools. It will make sure SystemTools is initialized
// before it is used and is the last static object destroyed.
static SystemToolsManager SystemToolsManagerInstance;
// Flags for use with TestFileAccess. Use a typedef in case any operating
// system in the future needs a special type. These are flags that may be
// combined using the | operator.
typedef int TestFilePermissions;
#if defined(_WIN32) && !defined(__CYGWIN__)
// On Windows (VC and Borland), no system header defines these constants...
static const TestFilePermissions TEST_FILE_OK = 0;
static const TestFilePermissions TEST_FILE_READ = 4;
static const TestFilePermissions TEST_FILE_WRITE = 2;
static const TestFilePermissions TEST_FILE_EXECUTE = 1;
#else
// Standard POSIX constants
static const TestFilePermissions TEST_FILE_OK = F_OK;
static const TestFilePermissions TEST_FILE_READ = R_OK;
static const TestFilePermissions TEST_FILE_WRITE = W_OK;
static const TestFilePermissions TEST_FILE_EXECUTE = X_OK;
#endif
/** \class SystemTools
* \brief A collection of useful platform-independent system functions.
*/
......@@ -113,34 +134,34 @@ public:
* all other are lowercased).
*/
static kwsys_stl::string Capitalized(const kwsys_stl::string&);
/**
* Return a 'capitalized words' string (i.e the first letter of each word
* is uppercased all other are left untouched though).
*/
static kwsys_stl::string CapitalizedWords(const kwsys_stl::string&);
/**
* Return a 'uncapitalized words' string (i.e the first letter of each word
* is lowercased all other are left untouched though).
*/
static kwsys_stl::string UnCapitalizedWords(const kwsys_stl::string&);
/**
* Return a lower case string
*/
static kwsys_stl::string LowerCase(const kwsys_stl::string&);
/**
* Return a lower case string
*/
static kwsys_stl::string UpperCase(const kwsys_stl::string&);
/**
* Count char in string
*/
static size_t CountChar(const char* str, char c);
/**
* Remove some characters from a string.
* Return a pointer to the new resulting string (allocated with 'new')
......@@ -152,13 +173,13 @@ public:
* Return a pointer to the new resulting string (allocated with 'new')
*/
static char* RemoveCharsButUpperHex(const char* str);
/**
* Replace some characters by another character in a string (in-place)
* Return a pointer to string
*/
static char* ReplaceChars(char* str, const char *toreplace,char replacement);
/**
* Returns true if str1 starts (respectively ends) with str2
*/
......@@ -171,25 +192,25 @@ public:
* Returns a pointer to the last occurence of str2 in str1
*/
static const char* FindLastString(const char* str1, const char* str2);
/**
* Make a duplicate of the string similar to the strdup C function
* but use new to create the 'new' string, so one can use
* 'delete' to remove it. Returns 0 if the input is empty.
*/
static char* DuplicateString(const char* str);
/**
* Return the string cropped to a given length by removing chars in the
* center of the string and replacing them with an ellipsis (...)
*/
static kwsys_stl::string CropString(const kwsys_stl::string&,size_t max_len);
/** split a path by separator into an array of strings, default is /.
If isPath is true then the string is treated like a path and if
s starts with a / then the first element of the returned array will
be /, so /foo/bar will be [/, foo, bar]
*/
*/
static kwsys_stl::vector<String> SplitString(const kwsys_stl::string& s, char separator = '/',
bool isPath = false);
/**
......@@ -197,7 +218,7 @@ public:
*/
static int Strucmp(const char *s1, const char *s2);
/**
/**
* Convert a string in __DATE__ or __TIMESTAMP__ format into a time_t.
* Return false on error, true on success
*/
......@@ -210,11 +231,11 @@ public:
*/
static bool Split(const kwsys_stl::string& s, kwsys_stl::vector<kwsys_stl::string>& l);
static bool Split(const kwsys_stl::string& s, kwsys_stl::vector<kwsys_stl::string>& l, char separator);
/**
/**
* Return string with space added between capitalized words
* (i.e. EatMyShorts becomes Eat My Shorts )
* (note that IEatShorts becomes IEat Shorts)
* (note that IEatShorts becomes IEat Shorts)
*/
static kwsys_stl::string AddSpaceBetweenCapitalizedWords(
const kwsys_stl::string&);
......@@ -290,15 +311,32 @@ public:
/**
* Return true if a file exists in the current directory.
* If isFile = true, then make sure the file is a file and
* If isFile = true, then make sure the file is a file and
* not a directory. If isFile = false, then return true
* if it is a file or a directory.
* if it is a file or a directory. Note that the file will
* also be checked for read access. (Currently, this check
* for read access is only done on POSIX systems.)
*/
static bool FileExists(const char* filename, bool isFile);
static bool FileExists(const kwsys_stl::string& filename, bool isFile);
static bool FileExists(const char* filename);
static bool FileExists(const kwsys_stl::string& filename);
/**
* Test if a file exists and can be accessed with the requested
* permissions. Symbolic links are followed. Returns true if
* the access test was successful.
*
* On POSIX systems (including Cygwin), this maps to the access
* function. On Windows systems, all existing files are
* considered readable, and writable files are considered to
* have the read-only file attribute cleared.
*/
static bool TestFileAccess(const char* filename,
TestFilePermissions permissions);
static bool TestFileAccess(const kwsys_stl::string& filename,
TestFilePermissions permissions);
/**
* Converts Cygwin path to Win32 path. Uses dictionary container for
* caching and calls to cygwin_conv_to_win32_path from Cygwin dll
......@@ -317,7 +355,7 @@ public:
Change the modification time or create a file
*/
static bool Touch(const kwsys_stl::string& filename, bool create);
/**
* Compare file modification times.
* Return true for successful comparison and false for error.
......@@ -360,7 +398,7 @@ public:
* to the running executable. If argv0 is not a full path,
* then this will try to find the full path. If the path is not
* found false is returned, if found true is returned. An error
* message of the attempted paths is stored in errorMsg.
* message of the attempted paths is stored in errorMsg.
* exeName is the name of the executable.
* buildDir is a possibly null path to the build directory.
* installPrefix is a possibly null pointer to the install directory.
......@@ -384,7 +422,7 @@ public:
static kwsys_stl::string CollapseFullPath(const kwsys_stl::string& in_relative,
const kwsys_stl::string& in_base);
/**
/**
* Get the real path for a given path, removing all symlinks. In
* the event of an error (non-existent path, permissions issue,
* etc.) the original path is returned if errorMessage pointer is
......@@ -469,31 +507,31 @@ public:
*/
static kwsys_stl::string GetFilenameLastExtension(
const kwsys_stl::string& filename);
/**
* Return file name without extension of a full filename
*/
static kwsys_stl::string GetFilenameWithoutExtension(
const kwsys_stl::string&);
/**
* Return file name without its last (shortest) extension
*/
static kwsys_stl::string GetFilenameWithoutLastExtension(
const kwsys_stl::string&);
/**
* Return whether the path represents a full path (not relative)
*/
static bool FileIsFullPath(const kwsys_stl::string&);
static bool FileIsFullPath(const char*);
/**
* For windows return the short path for the given path,
* Unix just a pass through
*/
static bool GetShortPath(const kwsys_stl::string& path, kwsys_stl::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
......@@ -501,7 +539,7 @@ public:
* end-of-file was reached. If the has_newline argument is specified, it will
* be true when the line read had a newline character.
*/
static bool GetLineFromStream(kwsys_ios::istream& istr,
static bool GetLineFromStream(kwsys_ios::istream& istr,
kwsys_stl::string& line,
bool* has_newline=0,
long sizeLimit=-1);
......@@ -529,7 +567,7 @@ public:
/**
* Make a new directory if it is not there. This function
* can make a full path even if none of the directories existed
* prior to calling this function.
* prior to calling this function.
*/
static bool MakeDirectory(const char* path);
static bool MakeDirectory(const kwsys_stl::string& path);
......@@ -572,12 +610,12 @@ public:
*/
static bool CopyADirectory(const kwsys_stl::string& source, const kwsys_stl::string& destination,
bool always = true);
/**
* Remove a file
*/
static bool RemoveFile(const kwsys_stl::string& source);
/**
* Remove a directory
*/
......@@ -593,7 +631,7 @@ public:
*/
static kwsys_stl::string FindFile(
const kwsys_stl::string& name,
const kwsys_stl::vector<kwsys_stl::string>& path =
const kwsys_stl::vector<kwsys_stl::string>& path =
kwsys_stl::vector<kwsys_stl::string>(),
bool no_system_path = false);
......@@ -602,7 +640,7 @@ public:
*/
static kwsys_stl::string FindDirectory(
const kwsys_stl::string& name,
const kwsys_stl::vector<kwsys_stl::string>& path =
const kwsys_stl::vector<kwsys_stl::string>& path =
kwsys_stl::vector<kwsys_stl::string>(),
bool no_system_path = false);
......@@ -631,17 +669,17 @@ public:
static kwsys_stl::string FindLibrary(
const kwsys_stl::string& name,
const kwsys_stl::vector<kwsys_stl::string>& path);
/**
* Return true if the file is a directory
*/
static bool FileIsDirectory(const kwsys_stl::string& name);
/**
* Return true if the file is a symlink
*/
static bool FileIsSymlink(const kwsys_stl::string& name);
/**
* Return true if the file has a given signature (first set of bytes)
*/
......@@ -657,15 +695,15 @@ public:
* The algorithm is simplistic, and should probably check for usual file
* extensions, 'magic' signature, unicode, etc.
*/
enum FileTypeEnum
{
enum FileTypeEnum
{
FileTypeUnknown,
FileTypeBinary,
FileTypeText
};
static SystemTools::FileTypeEnum DetectFileType(
const char* filename,
unsigned long length = 256,
const char* filename,
unsigned long length = 256,
double percent_bin = 0.05);
/**
......@@ -690,18 +728,18 @@ public:
* 'filename_found' is assigned the fully qualified name/path of the file
* if it is found (not touched otherwise).
* If 'try_filename_dirs' is true, try to find the file using the
* components of its path, i.e. if we are looking for c:/foo/bar/bill.txt,
* components of its path, i.e. if we are looking for c:/foo/bar/bill.txt,
* first look for bill.txt in 'dir', then in 'dir'/bar, then in 'dir'/foo/bar
* etc.
* Return true if the file was found, false otherwise.
*/
static bool LocateFileInDir(const char *filename,
const char *dir,
static bool LocateFileInDir(const char *filename,
const char *dir,
kwsys_stl::string& filename_found,
int try_filename_dirs = 0);
/** compute the relative path from local to remote. local must
be a directory. remote can be a file or a directory.
/** compute the relative path from local to remote. local must
be a directory. remote can be a file or a directory.
Both remote and local must be full paths. Basically, if
you are in directory local and you want to access the file in remote
what is the relative path to do that. For example:
......@@ -720,17 +758,27 @@ public:
*/
static long int CreationTime(const kwsys_stl::string& filename);
/**
* Visual C++ does not define mode_t (note that Borland does, however).
*/
#if defined( _MSC_VER )
typedef unsigned short mode_t;
#endif
/**
* Get and set permissions of the file.
* Get and set permissions of the file. If honor_umask is set, the umask
* is queried and applied to the given permissions. Returns false if
* failure.
*
* WARNING: A non-thread-safe method is currently used to get the umask
* if a honor_umask parameter is set to true.
*/
static bool GetPermissions(const char* file, mode_t& mode);
static bool GetPermissions(const kwsys_stl::string& file, mode_t& mode);
static bool SetPermissions(const char* file, mode_t mode);
static bool SetPermissions(const kwsys_stl::string& file, mode_t mode);
static bool SetPermissions(
const char* file, mode_t mode, bool honor_umask = false);
static bool SetPermissions(
const kwsys_stl::string& file, mode_t mode, bool honor_umask = false);
/** -----------------------------------------------------------------
* Time Manipulation Routines
......@@ -891,11 +939,11 @@ public:
* Return true if the string matches the format; false otherwise.
*/
static bool ParseURL( const kwsys_stl::string& URL,
kwsys_stl::string& protocol,
kwsys_stl::string& username,
kwsys_stl::string& password,
kwsys_stl::string& hostname,
kwsys_stl::string& dataport,
kwsys_stl::string& protocol,
kwsys_stl::string& username,
kwsys_stl::string& password,
kwsys_stl::string& hostname,
kwsys_stl::string& dataport,
kwsys_stl::string& datapath );
private:
......@@ -936,7 +984,7 @@ private:
*/
static kwsys_stl::string FindName(
const kwsys_stl::string& name,
const kwsys_stl::vector<kwsys_stl::string>& path =
const kwsys_stl::vector<kwsys_stl::string>& path =
kwsys_stl::vector<kwsys_stl::string>(),
bool no_system_path = false);
......
......@@ -21,6 +21,7 @@
#endif
#include <assert.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
......@@ -74,6 +75,16 @@ int runChild(const char* cmd[], int state, int exception, int value,
static int test1(int argc, const char* argv[])
{
/* This is a very basic functional test of kwsysProcess. It is repeated
numerous times to verify that there are no resource leaks in kwsysProcess
that eventually lead to an error. Many versions of OS X will fail after
256 leaked file handles, so 257 iterations seems to be a good test. On
the other hand, too many iterations will cause the test to time out -
especially if the test is instrumented with e.g. valgrind.
If you have problems with this test timing out on your system, or want to
run more than 257 iterations, you can change the number of iterations by
setting the KWSYS_TEST_PROCESS_1_COUNT environment variable. */
(void)argc; (void)argv;
fprintf(stdout, "Output on stdout from test returning 0.\n");
fprintf(stderr, "Output on stderr from test returning 0.\n");
......@@ -557,6 +568,10 @@ int runChild(const char* cmd[], int state, int exception, int value,
result = runChild2(kp, cmd, state, exception, value, share,
output, delay, timeout, poll, disown, createNewGroup,
interruptDelay);
if(result)
{
break;
}
}
kwsysProcess_Delete(kp);
return result;
......@@ -660,13 +675,24 @@ int main(int argc, const char* argv[])