summaryrefslogtreecommitdiffstats
path: root/Source/kwsys/SystemTools.cxx
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2003-04-08 17:10:44 (GMT)
committerBrad King <brad.king@kitware.com>2003-04-08 17:10:44 (GMT)
commit7dff3a7f69d1ec1e36d38903e94e433f6583d96e (patch)
tree52188fec4a7e35d1fd08e3ed6c3dcfbf1095a818 /Source/kwsys/SystemTools.cxx
parent7f48313225537a7bcc92c0f1c73754bdc50a2ca4 (diff)
downloadCMake-7dff3a7f69d1ec1e36d38903e94e433f6583d96e.zip
CMake-7dff3a7f69d1ec1e36d38903e94e433f6583d96e.tar.gz
CMake-7dff3a7f69d1ec1e36d38903e94e433f6583d96e.tar.bz2
ENH: Added kwsys library for platform-independent system tools.
Diffstat (limited to 'Source/kwsys/SystemTools.cxx')
-rw-r--r--Source/kwsys/SystemTools.cxx1793
1 files changed, 1793 insertions, 0 deletions
diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx
new file mode 100644
index 0000000..fca3f46
--- /dev/null
+++ b/Source/kwsys/SystemTools.cxx
@@ -0,0 +1,1793 @@
+/*=========================================================================
+
+ Program: KWSys - Kitware System Library
+ Module: $RCSfile$
+ Language: C++
+ Date: $Date$
+ Version: $Revision$
+
+ Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
+ See http://www.cmake.org/HTML/Copyright.html for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE. See the above copyright notices for more information.
+
+=========================================================================*/
+#include <SystemTools.hxx>
+#include <RegularExpression.hxx>
+#include <Directory.hxx>
+
+#include <fstream>
+
+#include <stdio.h>
+#include <sys/stat.h>
+#include <ctype.h>
+#include <errno.h>
+#include <time.h>
+
+// support for realpath call
+#ifndef _WIN32
+#include <limits.h>
+#include <stdlib.h>
+#include <sys/param.h>
+#include <sys/wait.h>
+#endif
+
+#if defined(_WIN32) && (defined(_MSC_VER) || defined(__BORLANDC__))
+#include <string.h>
+#include <windows.h>
+#include <direct.h>
+#define _unlink unlink
+inline int Mkdir(const char* dir)
+{
+ return _mkdir(dir);
+}
+inline const char* Getcwd(char* buf, unsigned int len)
+{
+ return _getcwd(buf, len);
+}
+inline int Chdir(const char* dir)
+{
+ #if defined(__BORLANDC__)
+ return chdir(dir);
+ #else
+ return _chdir(dir);
+ #endif
+}
+#else
+#include <sys/types.h>
+#include <fcntl.h>
+#include <unistd.h>
+inline int Mkdir(const char* dir)
+{
+ return mkdir(dir, 00777);
+}
+inline const char* Getcwd(char* buf, unsigned int len)
+{
+ return getcwd(buf, len);
+}
+inline int Chdir(const char* dir)
+{
+ return chdir(dir);
+}
+#endif
+
+
+/* Implement floattime() for various platforms */
+// Taken from Python 2.1.3
+
+#if defined( _WIN32 ) && !defined( __CYGWIN__ )
+# include <sys/timeb.h>
+# define HAVE_FTIME
+# if defined( __BORLANDC__)
+# define FTIME ftime
+# define TIMEB timeb
+# else // Visual studio?
+# define FTIME _ftime
+# define TIMEB _timeb
+# endif
+#elif defined( __CYGWIN__ ) || defined( __linux__ )
+# include <sys/time.h>
+# include <time.h>
+# define HAVE_GETTIMEOFDAY
+#endif
+
+namespace KWSYS_NAMESPACE
+{
+
+double
+SystemTools::GetTime(void)
+{
+ /* There are three ways to get the time:
+ (1) gettimeofday() -- resolution in microseconds
+ (2) ftime() -- resolution in milliseconds
+ (3) time() -- resolution in seconds
+ In all cases the return value is a float in seconds.
+ Since on some systems (e.g. SCO ODT 3.0) gettimeofday() may
+ fail, so we fall back on ftime() or time().
+ Note: clock resolution does not imply clock accuracy! */
+#ifdef HAVE_GETTIMEOFDAY
+ {
+ struct timeval t;
+#ifdef GETTIMEOFDAY_NO_TZ
+ if (gettimeofday(&t) == 0)
+ return (double)t.tv_sec + t.tv_usec*0.000001;
+#else /* !GETTIMEOFDAY_NO_TZ */
+ if (gettimeofday(&t, (struct timezone *)NULL) == 0)
+ return (double)t.tv_sec + t.tv_usec*0.000001;
+#endif /* !GETTIMEOFDAY_NO_TZ */
+ }
+#endif /* !HAVE_GETTIMEOFDAY */
+ {
+#if defined(HAVE_FTIME)
+ struct TIMEB t;
+ FTIME(&t);
+ return (double)t.time + (double)t.millitm * (double)0.001;
+#else /* !HAVE_FTIME */
+ time_t secs;
+ time(&secs);
+ return (double)secs;
+#endif /* !HAVE_FTIME */
+ }
+}
+
+// adds the elements of the env variable path to the arg passed in
+void SystemTools::GetPath(kwsys_std::vector<kwsys_std::string>& path)
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ const char* pathSep = ";";
+#else
+ const char* pathSep = ":";
+#endif
+ kwsys_std::string pathEnv = getenv("PATH");
+ // A hack to make the below algorithm work.
+ if(pathEnv[pathEnv.length()-1] != ':')
+ {
+ pathEnv += pathSep;
+ }
+ kwsys_std::string::size_type start =0;
+ bool done = false;
+ while(!done)
+ {
+ kwsys_std::string::size_type endpos = pathEnv.find(pathSep, start);
+ if(endpos != kwsys_std::string::npos)
+ {
+ path.push_back(pathEnv.substr(start, endpos-start));
+ start = endpos+1;
+ }
+ else
+ {
+ done = true;
+ }
+ }
+ for(kwsys_std::vector<kwsys_std::string>::iterator i = path.begin();
+ i != path.end(); ++i)
+ {
+ SystemTools::ConvertToUnixSlashes(*i);
+ }
+}
+
+
+const char* SystemTools::GetExecutableExtension()
+{
+#if defined(_WIN32) || defined(__CYGWIN__)
+ return ".exe";
+#else
+ return "";
+#endif
+}
+
+
+bool SystemTools::MakeDirectory(const char* path)
+{
+ if(SystemTools::FileExists(path))
+ {
+ return true;
+ }
+ kwsys_std::string dir = path;
+ if(dir.size() == 0)
+ {
+ return false;
+ }
+ SystemTools::ConvertToUnixSlashes(dir);
+
+ kwsys_std::string::size_type pos = dir.find(':');
+ if(pos == kwsys_std::string::npos)
+ {
+ pos = 0;
+ }
+ kwsys_std::string topdir;
+ while((pos = dir.find('/', pos)) != kwsys_std::string::npos)
+ {
+ topdir = dir.substr(0, pos);
+ Mkdir(topdir.c_str());
+ pos++;
+ }
+ if(dir[dir.size()-1] == '/')
+ {
+ topdir = dir.substr(0, dir.size());
+ }
+ else
+ {
+ topdir = dir;
+ }
+ if(Mkdir(topdir.c_str()) != 0)
+ {
+ // There is a bug in the Borland Run time library which makes MKDIR
+ // return EACCES when it should return EEXISTS
+ // if it is some other error besides directory exists
+ // then return false
+ if( (errno != EEXIST)
+#ifdef __BORLANDC__
+ && (errno != EACCES)
+#endif
+ )
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+
+// replace replace with with as many times as it shows up in source.
+// write the result into source.
+void SystemTools::ReplaceString(kwsys_std::string& source,
+ const char* replace,
+ const char* with)
+{
+ // get out quick if string is not found
+ kwsys_std::string::size_type start = source.find(replace);
+ if(start == kwsys_std::string::npos)
+ {
+ return;
+ }
+ kwsys_std::string rest;
+ kwsys_std::string::size_type lengthReplace = strlen(replace);
+ kwsys_std::string::size_type lengthWith = strlen(with);
+ while(start != kwsys_std::string::npos)
+ {
+ rest = source.substr(start+lengthReplace);
+ source = source.substr(0, start);
+ source += with;
+ source += rest;
+ start = source.find(replace, start + lengthWith );
+ }
+}
+
+// Read a registry value.
+// Example :
+// HKEY_LOCAL_MACHINE\SOFTWARE\Python\PythonCore\2.1\InstallPath
+// => will return the data of the "default" value of the key
+// HKEY_LOCAL_MACHINE\SOFTWARE\Scriptics\Tcl\8.4;Root
+// => will return the data of the "Root" value of the key
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+bool SystemTools::ReadRegistryValue(const char *key, kwsys_std::string &value)
+{
+
+ kwsys_std::string primary = key;
+ kwsys_std::string second;
+ kwsys_std::string valuename;
+
+ size_t start = primary.find("\\");
+ if (start == kwsys_std::string::npos)
+ {
+ return false;
+ }
+
+ size_t valuenamepos = primary.find(";");
+ if (valuenamepos != kwsys_std::string::npos)
+ {
+ valuename = primary.substr(valuenamepos+1);
+ }
+
+ second = primary.substr(start+1, valuenamepos-start-1);
+ primary = primary.substr(0, start);
+
+ HKEY primaryKey;
+ if (primary == "HKEY_CURRENT_USER")
+ {
+ primaryKey = HKEY_CURRENT_USER;
+ }
+ if (primary == "HKEY_CURRENT_CONFIG")
+ {
+ primaryKey = HKEY_CURRENT_CONFIG;
+ }
+ if (primary == "HKEY_CLASSES_ROOT")
+ {
+ primaryKey = HKEY_CLASSES_ROOT;
+ }
+ if (primary == "HKEY_LOCAL_MACHINE")
+ {
+ primaryKey = HKEY_LOCAL_MACHINE;
+ }
+ if (primary == "HKEY_USERS")
+ {
+ primaryKey = HKEY_USERS;
+ }
+
+ HKEY hKey;
+ if(RegOpenKeyEx(primaryKey,
+ second.c_str(),
+ 0,
+ KEY_READ,
+ &hKey) != ERROR_SUCCESS)
+ {
+ return false;
+ }
+ else
+ {
+ DWORD dwType, dwSize;
+ dwSize = 1023;
+ char data[1024];
+ if(RegQueryValueEx(hKey,
+ (LPTSTR)valuename.c_str(),
+ NULL,
+ &dwType,
+ (BYTE *)data,
+ &dwSize) == ERROR_SUCCESS)
+ {
+ if (dwType == REG_SZ)
+ {
+ value = data;
+ return true;
+ }
+ }
+ }
+ return false;
+}
+#else
+bool SystemTools::ReadRegistryValue(const char *, kwsys_std::string &)
+{
+ return false;
+}
+#endif
+
+
+// Write a registry value.
+// Example :
+// HKEY_LOCAL_MACHINE\SOFTWARE\Python\PythonCore\2.1\InstallPath
+// => will set the data of the "default" value of the key
+// HKEY_LOCAL_MACHINE\SOFTWARE\Scriptics\Tcl\8.4;Root
+// => will set the data of the "Root" value of the key
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+bool SystemTools::WriteRegistryValue(const char *key, const char *value)
+{
+ kwsys_std::string primary = key;
+ kwsys_std::string second;
+ kwsys_std::string valuename;
+
+ size_t start = primary.find("\\");
+ if (start == kwsys_std::string::npos)
+ {
+ return false;
+ }
+
+ size_t valuenamepos = primary.find(";");
+ if (valuenamepos != kwsys_std::string::npos)
+ {
+ valuename = primary.substr(valuenamepos+1);
+ }
+
+ second = primary.substr(start+1, valuenamepos-start-1);
+ primary = primary.substr(0, start);
+
+ HKEY primaryKey;
+ if (primary == "HKEY_CURRENT_USER")
+ {
+ primaryKey = HKEY_CURRENT_USER;
+ }
+ if (primary == "HKEY_CURRENT_CONFIG")
+ {
+ primaryKey = HKEY_CURRENT_CONFIG;
+ }
+ if (primary == "HKEY_CLASSES_ROOT")
+ {
+ primaryKey = HKEY_CLASSES_ROOT;
+ }
+ if (primary == "HKEY_LOCAL_MACHINE")
+ {
+ primaryKey = HKEY_LOCAL_MACHINE;
+ }
+ if (primary == "HKEY_USERS")
+ {
+ primaryKey = HKEY_USERS;
+ }
+
+ HKEY hKey;
+ DWORD dwDummy;
+ if(RegCreateKeyEx(primaryKey,
+ second.c_str(),
+ 0,
+ "",
+ REG_OPTION_NON_VOLATILE,
+ KEY_WRITE,
+ NULL,
+ &hKey,
+ &dwDummy) != ERROR_SUCCESS)
+ {
+ return false;
+ }
+
+ if(RegSetValueEx(hKey,
+ (LPTSTR)valuename.c_str(),
+ 0,
+ REG_SZ,
+ (CONST BYTE *)value,
+ (DWORD)(strlen(value) + 1)) == ERROR_SUCCESS)
+ {
+ return true;
+ }
+ return false;
+}
+#else
+bool SystemTools::WriteRegistryValue(const char *, const char *)
+{
+ return false;
+}
+#endif
+
+// Delete a registry value.
+// Example :
+// HKEY_LOCAL_MACHINE\SOFTWARE\Python\PythonCore\2.1\InstallPath
+// => will delete the data of the "default" value of the key
+// HKEY_LOCAL_MACHINE\SOFTWARE\Scriptics\Tcl\8.4;Root
+// => will delete the data of the "Root" value of the key
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+bool SystemTools::DeleteRegistryValue(const char *key)
+{
+ kwsys_std::string primary = key;
+ kwsys_std::string second;
+ kwsys_std::string valuename;
+
+ size_t start = primary.find("\\");
+ if (start == kwsys_std::string::npos)
+ {
+ return false;
+ }
+
+ size_t valuenamepos = primary.find(";");
+ if (valuenamepos != kwsys_std::string::npos)
+ {
+ valuename = primary.substr(valuenamepos+1);
+ }
+
+ second = primary.substr(start+1, valuenamepos-start-1);
+ primary = primary.substr(0, start);
+
+ HKEY primaryKey;
+ if (primary == "HKEY_CURRENT_USER")
+ {
+ primaryKey = HKEY_CURRENT_USER;
+ }
+ if (primary == "HKEY_CURRENT_CONFIG")
+ {
+ primaryKey = HKEY_CURRENT_CONFIG;
+ }
+ if (primary == "HKEY_CLASSES_ROOT")
+ {
+ primaryKey = HKEY_CLASSES_ROOT;
+ }
+ if (primary == "HKEY_LOCAL_MACHINE")
+ {
+ primaryKey = HKEY_LOCAL_MACHINE;
+ }
+ if (primary == "HKEY_USERS")
+ {
+ primaryKey = HKEY_USERS;
+ }
+
+ HKEY hKey;
+ if(RegOpenKeyEx(primaryKey,
+ second.c_str(),
+ 0,
+ KEY_WRITE,
+ &hKey) != ERROR_SUCCESS)
+ {
+ return false;
+ }
+ else
+ {
+ if(RegDeleteValue(hKey,
+ (LPTSTR)valuename.c_str()) == ERROR_SUCCESS)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+#else
+bool SystemTools::DeleteRegistryValue(const char *)
+{
+ return false;
+}
+#endif
+
+// replace replace with with as many times as it shows up in source.
+// write the result into source.
+#if defined(_WIN32) && !defined(__CYGWIN__)
+void SystemTools::ExpandRegistryValues(kwsys_std::string& source)
+{
+ // Regular expression to match anything inside [...] that begins in HKEY.
+ // Note that there is a special rule for regular expressions to match a
+ // close square-bracket inside a list delimited by square brackets.
+ // The "[^]]" part of this expression will match any character except
+ // a close square-bracket. The ']' character must be the first in the
+ // list of characters inside the [^...] block of the expression.
+ cmRegularExpression regEntry("\\[(HKEY[^]]*)\\]");
+
+ // check for black line or comment
+ while (regEntry.find(source))
+ {
+ // the arguments are the second match
+ kwsys_std::string key = regEntry.match(1);
+ kwsys_std::string val;
+ if (ReadRegistryValue(key.c_str(), val))
+ {
+ kwsys_std::string reg = "[";
+ reg += key + "]";
+ SystemTools::ReplaceString(source, reg.c_str(), val.c_str());
+ }
+ else
+ {
+ kwsys_std::string reg = "[";
+ reg += key + "]";
+ SystemTools::ReplaceString(source, reg.c_str(), "/registry");
+ }
+ }
+}
+#else
+void SystemTools::ExpandRegistryValues(kwsys_std::string&)
+{
+}
+#endif
+
+
+kwsys_std::string SystemTools::EscapeQuotes(const char* str)
+{
+ kwsys_std::string result = "";
+ for(const char* ch = str; *ch != '\0'; ++ch)
+ {
+ if(*ch == '"')
+ {
+ result += '\\';
+ }
+ result += *ch;
+ }
+ return result;
+}
+
+bool SystemTools::SameFile(const char* file1, const char* file2)
+{
+#ifdef _WIN32
+ HANDLE hFile1, hFile2;
+
+ hFile1 = CreateFile( file1,
+ GENERIC_READ,
+ FILE_SHARE_READ ,
+ NULL,
+ OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS,
+ NULL
+ );
+ hFile2 = CreateFile( file2,
+ GENERIC_READ,
+ FILE_SHARE_READ,
+ NULL,
+ OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS,
+ NULL
+ );
+ if( hFile1 == INVALID_HANDLE_VALUE || hFile2 == INVALID_HANDLE_VALUE)
+ {
+ if(hFile1 != INVALID_HANDLE_VALUE)
+ {
+ CloseHandle(hFile1);
+ }
+ if(hFile2 != INVALID_HANDLE_VALUE)
+ {
+ CloseHandle(hFile2);
+ }
+ return false;
+ }
+
+ BY_HANDLE_FILE_INFORMATION fiBuf1;
+ BY_HANDLE_FILE_INFORMATION fiBuf2;
+ GetFileInformationByHandle( hFile1, &fiBuf1 );
+ GetFileInformationByHandle( hFile2, &fiBuf2 );
+ CloseHandle(hFile1);
+ CloseHandle(hFile2);
+ return (fiBuf1.nFileIndexHigh == fiBuf2.nFileIndexHigh &&
+ fiBuf1.nFileIndexLow == fiBuf2.nFileIndexLow);
+#else
+ struct stat fileStat1, fileStat2;
+ if (stat(file1, &fileStat1) == 0 && stat(file2, &fileStat2) == 0)
+ {
+ // see if the files are the same file
+ // check the device inode and size
+ if(memcmp(&fileStat2.st_dev, &fileStat1.st_dev, sizeof(fileStat1.st_dev)) == 0 &&
+ memcmp(&fileStat2.st_ino, &fileStat1.st_ino, sizeof(fileStat1.st_ino)) == 0 &&
+ fileStat2.st_size == fileStat1.st_size
+ )
+ {
+ return true;
+ }
+ }
+ return false;
+#endif
+}
+
+
+// return true if the file exists
+bool SystemTools::FileExists(const char* filename)
+{
+ struct stat fs;
+ if (stat(filename, &fs) != 0)
+ {
+ return false;
+ }
+ else
+ {
+ return true;
+ }
+}
+
+
+// Return a capitalized string (i.e the first letter is uppercased, all other
+// are lowercased)
+kwsys_std::string SystemTools::Capitalized(const kwsys_std::string& s)
+{
+ kwsys_std::string n;
+ n.resize(s.size());
+ n[0] = toupper(s[0]);
+ for (size_t i = 1; i < s.size(); i++)
+ {
+ n[i] = tolower(s[i]);
+ }
+ return n;
+}
+
+
+// Return a lower case string
+kwsys_std::string SystemTools::LowerCase(const kwsys_std::string& s)
+{
+ kwsys_std::string n;
+ n.resize(s.size());
+ for (size_t i = 0; i < s.size(); i++)
+ {
+ n[i] = tolower(s[i]);
+ }
+ return n;
+}
+
+// Return a lower case string
+kwsys_std::string SystemTools::UpperCase(const kwsys_std::string& s)
+{
+ kwsys_std::string n;
+ n.resize(s.size());
+ for (size_t i = 0; i < s.size(); i++)
+ {
+ n[i] = toupper(s[i]);
+ }
+ return n;
+}
+
+
+// convert windows slashes to unix slashes
+void SystemTools::ConvertToUnixSlashes(kwsys_std::string& path)
+{
+ kwsys_std::string::size_type pos = 0;
+ while((pos = path.find('\\', pos)) != kwsys_std::string::npos)
+ {
+ path[pos] = '/';
+ pos++;
+ }
+ // Remove all // from the path just like most unix shells
+ int start_find = 0;
+
+#ifdef _WIN32
+ // However, on windows if the first characters are both slashes,
+ // then keep them that way, so that network paths can be handled.
+ start_find = 1;
+#endif
+
+ while((pos = path.find("//", start_find)) != kwsys_std::string::npos)
+ {
+ SystemTools::ReplaceString(path, "//", "/");
+ }
+
+ // remove any trailing slash
+ if(path.size() && path[path.size()-1] == '/')
+ {
+ path = path.substr(0, path.size()-1);
+ }
+
+ // if there is a tilda ~ then replace it with HOME
+ if(path.find("~") == 0)
+ {
+ if (getenv("HOME"))
+ {
+ path = kwsys_std::string(getenv("HOME")) + path.substr(1);
+ }
+ }
+
+ // if there is a /tmp_mnt in a path get rid of it!
+ // stupid sgi's
+ if(path.find("/tmp_mnt") == 0)
+ {
+ path = path.substr(8);
+ }
+}
+
+
+// change // to /, and escape any spaces in the path
+kwsys_std::string SystemTools::ConvertToUnixOutputPath(const char* path)
+{
+ kwsys_std::string ret = path;
+
+ // remove // except at the beginning might be a cygwin drive
+ kwsys_std::string::size_type pos = 1;
+ while((pos = ret.find("//", pos)) != kwsys_std::string::npos)
+ {
+ ret.erase(pos, 1);
+ }
+ // now escape spaces if there is a space in the path
+ if(ret.find(" ") != kwsys_std::string::npos)
+ {
+ kwsys_std::string result = "";
+ char lastch = 1;
+ for(const char* ch = ret.c_str(); *ch != '\0'; ++ch)
+ {
+ // if it is already escaped then don't try to escape it again
+ if(*ch == ' ' && lastch != '\\')
+ {
+ result += '\\';
+ }
+ result += *ch;
+ lastch = *ch;
+ }
+ ret = result;
+ }
+ return ret;
+}
+
+
+
+kwsys_std::string SystemTools::EscapeSpaces(const char* str)
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ kwsys_std::string result;
+
+ // if there are spaces
+ kwsys_std::string temp = str;
+ if (temp.find(" ") != kwsys_std::string::npos &&
+ temp.find("\"")==kwsys_std::string::npos)
+ {
+ result = "\"";
+ result += str;
+ result += "\"";
+ return result;
+ }
+ return str;
+#else
+ kwsys_std::string result = "";
+ for(const char* ch = str; *ch != '\0'; ++ch)
+ {
+ if(*ch == ' ')
+ {
+ result += '\\';
+ }
+ result += *ch;
+ }
+ return result;
+#endif
+}
+
+kwsys_std::string SystemTools::ConvertToOutputPath(const char* path)
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ return SystemTools::ConvertToWindowsOutputPath(path);
+#else
+ return SystemTools::ConvertToUnixOutputPath(path);
+#endif
+}
+
+
+// remove double slashes not at the start
+kwsys_std::string SystemTools::ConvertToWindowsOutputPath(const char* path)
+{
+ kwsys_std::string ret = path;
+ kwsys_std::string::size_type pos = 0;
+ // first convert all of the slashes
+ while((pos = ret.find('/', pos)) != kwsys_std::string::npos)
+ {
+ ret[pos] = '\\';
+ pos++;
+ }
+ // check for really small paths
+ if(ret.size() < 2)
+ {
+ return ret;
+ }
+ // now clean up a bit and remove double slashes
+ // Only if it is not the first position in the path which is a network
+ // path on windows
+ pos = 1; // start at position 1
+ if(ret[0] == '\"')
+ {
+ pos = 2; // if the string is already quoted then start at 2
+ if(ret.size() < 3)
+ {
+ return ret;
+ }
+ }
+ while((pos = ret.find("\\\\", pos)) != kwsys_std::string::npos)
+ {
+ ret.erase(pos, 1);
+ }
+ // now double quote the path if it has spaces in it
+ // and is not already double quoted
+ if(ret.find(" ") != kwsys_std::string::npos
+ && ret[0] != '\"')
+ {
+ kwsys_std::string result;
+ result = "\"" + ret + "\"";
+ ret = result;
+ }
+ return ret;
+}
+
+bool SystemTools::CopyFileIfDifferent(const char* source,
+ const char* destination)
+{
+ if(SystemTools::FilesDiffer(source, destination))
+ {
+ SystemTools::CopyFileAlways(source, destination);
+ return true;
+ }
+ return false;
+}
+
+
+bool SystemTools::FilesDiffer(const char* source,
+ const char* destination)
+{
+ struct stat statSource;
+ if (stat(source, &statSource) != 0)
+ {
+ return true;
+ }
+
+ struct stat statDestination;
+ if (stat(destination, &statDestination) != 0)
+ {
+ return true;
+ }
+
+ if(statSource.st_size != statDestination.st_size)
+ {
+ return true;
+ }
+
+ if(statSource.st_size == 0)
+ {
+ return false;
+ }
+
+#if defined(_WIN32) || defined(__CYGWIN__)
+ kwsys_std::ifstream finSource(source,
+ kwsys_std::ios::binary | kwsys_std::ios::in);
+ kwsys_std::ifstream finDestination(destination,
+ kwsys_std::ios::binary | kwsys_std::ios::in);
+#else
+ kwsys_std::ifstream finSource(source);
+ kwsys_std::ifstream finDestination(destination);
+#endif
+ if(!finSource || !finDestination)
+ {
+ return true;
+ }
+
+ char* source_buf = new char[statSource.st_size];
+ char* dest_buf = new char[statSource.st_size];
+
+ finSource.read(source_buf, statSource.st_size);
+ finDestination.read(dest_buf, statSource.st_size);
+
+ if(statSource.st_size != static_cast<long>(finSource.gcount()) ||
+ statSource.st_size != static_cast<long>(finDestination.gcount()))
+ {
+ // Failed to read files.
+ delete [] source_buf;
+ delete [] dest_buf;
+ return true;
+ }
+ int ret = memcmp((const void*)source_buf,
+ (const void*)dest_buf,
+ statSource.st_size);
+
+ delete [] dest_buf;
+ delete [] source_buf;
+
+ return ret != 0;
+}
+
+
+/**
+ * Copy a file named by "source" to the file named by "destination".
+ */
+bool SystemTools::CopyFileAlways(const char* source, const char* destination)
+{
+ const int bufferSize = 4096;
+ char buffer[bufferSize];
+
+ // If destination is a directory, try to create a file with the same
+ // name as the source in that directory.
+
+ kwsys_std::string new_destination;
+ if(SystemTools::FileExists(destination) &&
+ SystemTools::FileIsDirectory(destination))
+ {
+ new_destination = destination;
+ SystemTools::ConvertToUnixSlashes(new_destination);
+ new_destination += '/';
+ kwsys_std::string source_name = source;
+ new_destination += SystemTools::GetFilenameName(source_name);
+ destination = new_destination.c_str();
+ }
+
+ // Create destination directory
+
+ kwsys_std::string destination_dir = destination;
+ destination_dir = SystemTools::GetFilenamePath(destination_dir);
+ SystemTools::MakeDirectory(destination_dir.c_str());
+
+ // Open files
+
+#if defined(_WIN32) || defined(__CYGWIN__)
+ kwsys_std::ifstream fin(source,
+ kwsys_std::ios::binary | kwsys_std::ios::in);
+#else
+ kwsys_std::ifstream fin(source);
+#endif
+ if(!fin)
+ {
+ return false;
+ }
+
+#if defined(_WIN32) || defined(__CYGWIN__)
+ kwsys_std::ofstream fout(destination,
+ kwsys_std::ios::binary | kwsys_std::ios::out | kwsys_std::ios::trunc);
+#else
+ kwsys_std::ofstream fout(destination,
+ kwsys_std::ios::out | kwsys_std::ios::trunc);
+#endif
+ if(!fout)
+ {
+ return false;
+ }
+
+ // This copy loop is very sensitive on certain platforms with
+ // slightly broken stream libraries (like HPUX). Normally, it is
+ // incorrect to not check the error condition on the fin.read()
+ // before using the data, but the fin.gcount() will be zero if an
+ // error occurred. Therefore, the loop should be safe everywhere.
+ while(fin)
+ {
+ fin.read(buffer, bufferSize);
+ if(fin.gcount())
+ {
+ fout.write(buffer, fin.gcount());
+ }
+ }
+
+ // Make sure the operating system has finished writing the file
+ // before closing it. This will ensure the file is finished before
+ // the check below.
+ fout.flush();
+
+ fin.close();
+ fout.close();
+
+ // More checks.
+ struct stat statSource, statDestination;
+ statSource.st_size = 12345;
+ statDestination.st_size = 12345;
+ if(stat(source, &statSource) != 0)
+ {
+ return false;
+ }
+ else if(stat(destination, &statDestination) != 0)
+ {
+ return false;
+ }
+ else if(statSource.st_size != statDestination.st_size)
+ {
+ return false;
+ }
+ return true;
+}
+
+// return true if the file exists
+long int SystemTools::ModifiedTime(const char* filename)
+{
+ struct stat fs;
+ if (stat(filename, &fs) != 0)
+ {
+ return 0;
+ }
+ else
+ {
+ return (long int)fs.st_mtime;
+ }
+}
+
+
+kwsys_std::string SystemTools::GetLastSystemError()
+{
+ int e = errno;
+ return strerror(e);
+}
+
+bool SystemTools::RemoveFile(const char* source)
+{
+ return unlink(source) != 0 ? false : true;
+}
+
+/**
+ * Find the file the given name. Searches the given path and then
+ * the system search path. Returns the full path to the file if it is
+ * found. Otherwise, the empty string is returned.
+ */
+kwsys_std::string SystemTools::FindFile(const char* name,
+ const kwsys_std::vector<kwsys_std::string>& userPaths)
+{
+ // Add the system search path to our path.
+ kwsys_std::vector<kwsys_std::string> path = userPaths;
+ SystemTools::GetPath(path);
+
+ kwsys_std::string tryPath;
+ for(kwsys_std::vector<kwsys_std::string>::const_iterator p = path.begin();
+ p != path.end(); ++p)
+ {
+ tryPath = *p;
+ tryPath += "/";
+ tryPath += name;
+ if(SystemTools::FileExists(tryPath.c_str()) &&
+ !SystemTools::FileIsDirectory(tryPath.c_str()))
+ {
+ return SystemTools::CollapseFullPath(tryPath.c_str());
+ }
+ }
+ // Couldn't find the file.
+ return "";
+}
+
+/**
+ * Find the executable with the given name. Searches the given path and then
+ * the system search path. Returns the full path to the executable if it is
+ * found. Otherwise, the empty string is returned.
+ */
+kwsys_std::string SystemTools::FindProgram(const char* name,
+ const kwsys_std::vector<kwsys_std::string>& userPaths,
+ bool no_system_path)
+{
+ if(!name)
+ {
+ return "";
+ }
+ // See if the executable exists as written.
+ if(SystemTools::FileExists(name) &&
+ !SystemTools::FileIsDirectory(name))
+ {
+ return SystemTools::CollapseFullPath(name);
+ }
+ kwsys_std::string tryPath = name;
+ tryPath += SystemTools::GetExecutableExtension();
+ if(SystemTools::FileExists(tryPath.c_str()) &&
+ !SystemTools::FileIsDirectory(tryPath.c_str()))
+ {
+ return SystemTools::CollapseFullPath(tryPath.c_str());
+ }
+
+ // Add the system search path to our path.
+ kwsys_std::vector<kwsys_std::string> path = userPaths;
+ if (!no_system_path)
+ {
+ SystemTools::GetPath(path);
+ }
+
+ for(kwsys_std::vector<kwsys_std::string>::const_iterator p = path.begin();
+ p != path.end(); ++p)
+ {
+ tryPath = *p;
+ tryPath += "/";
+ tryPath += name;
+ if(SystemTools::FileExists(tryPath.c_str()) &&
+ !SystemTools::FileIsDirectory(tryPath.c_str()))
+ {
+ return SystemTools::CollapseFullPath(tryPath.c_str());
+ }
+#ifdef _WIN32
+ tryPath += ".com";
+ if(SystemTools::FileExists(tryPath.c_str()) &&
+ !SystemTools::FileIsDirectory(tryPath.c_str()))
+ {
+ return SystemTools::CollapseFullPath(tryPath.c_str());
+ }
+ tryPath = *p;
+ tryPath += "/";
+ tryPath += name;
+#endif
+ tryPath += SystemTools::GetExecutableExtension();
+ if(SystemTools::FileExists(tryPath.c_str()) &&
+ !SystemTools::FileIsDirectory(tryPath.c_str()))
+ {
+ return SystemTools::CollapseFullPath(tryPath.c_str());
+ }
+ }
+
+ // Couldn't find the program.
+ return "";
+}
+
+
+/**
+ * Find the library with the given name. Searches the given path and then
+ * the system search path. Returns the full path to the library if it is
+ * found. Otherwise, the empty string is returned.
+ */
+kwsys_std::string SystemTools::FindLibrary(const char* name,
+ const kwsys_std::vector<kwsys_std::string>& userPaths)
+{
+ // See if the executable exists as written.
+ if(SystemTools::FileExists(name) &&
+ !SystemTools::FileIsDirectory(name))
+ {
+ return SystemTools::CollapseFullPath(name);
+ }
+
+ // Add the system search path to our path.
+ kwsys_std::vector<kwsys_std::string> path = userPaths;
+ SystemTools::GetPath(path);
+
+ kwsys_std::string tryPath;
+ for(kwsys_std::vector<kwsys_std::string>::const_iterator p = path.begin();
+ p != path.end(); ++p)
+ {
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ tryPath = *p;
+ tryPath += "/";
+ tryPath += name;
+ tryPath += ".lib";
+ if(SystemTools::FileExists(tryPath.c_str()))
+ {
+ return SystemTools::CollapseFullPath(tryPath.c_str());
+ }
+#else
+ tryPath = *p;
+ tryPath += "/lib";
+ tryPath += name;
+ tryPath += ".so";
+ if(SystemTools::FileExists(tryPath.c_str()))
+ {
+ return SystemTools::CollapseFullPath(tryPath.c_str());
+ }
+ tryPath = *p;
+ tryPath += "/lib";
+ tryPath += name;
+ tryPath += ".a";
+ if(SystemTools::FileExists(tryPath.c_str()))
+ {
+ return SystemTools::CollapseFullPath(tryPath.c_str());
+ }
+ tryPath = *p;
+ tryPath += "/lib";
+ tryPath += name;
+ tryPath += ".sl";
+ if(SystemTools::FileExists(tryPath.c_str()))
+ {
+ return SystemTools::CollapseFullPath(tryPath.c_str());
+ }
+ tryPath = *p;
+ tryPath += "/lib";
+ tryPath += name;
+ tryPath += ".dylib";
+ if(SystemTools::FileExists(tryPath.c_str()))
+ {
+ return SystemTools::CollapseFullPath(tryPath.c_str());
+ }
+#endif
+ }
+
+ // Couldn't find the library.
+ return "";
+}
+
+bool SystemTools::FileIsDirectory(const char* name)
+{
+ struct stat fs;
+ if(stat(name, &fs) == 0)
+ {
+#if _WIN32
+ return ((fs.st_mode & _S_IFDIR) != 0);
+#else
+ return S_ISDIR(fs.st_mode);
+#endif
+ }
+ else
+ {
+ return false;
+ }
+}
+
+int SystemTools::ChangeDirectory(const char *dir)
+{
+ return Chdir(dir);
+}
+
+kwsys_std::string SystemTools::GetCurrentWorkingDirectory()
+{
+ char buf[2048];
+ kwsys_std::string path = Getcwd(buf, 2048);
+ return path;
+}
+
+kwsys_std::string SystemTools::GetProgramPath(const char* in_name)
+{
+ kwsys_std::string dir, file;
+ SystemTools::SplitProgramPath(in_name, dir, file);
+ return dir;
+}
+
+bool SystemTools::SplitProgramPath(const char* in_name,
+ kwsys_std::string& dir,
+ kwsys_std::string& file,
+ bool errorReport)
+{
+ dir = in_name;
+ file = "";
+ SystemTools::ConvertToUnixSlashes(dir);
+
+ if(!SystemTools::FileIsDirectory(dir.c_str()))
+ {
+ kwsys_std::string::size_type slashPos = dir.rfind("/");
+ if(slashPos != kwsys_std::string::npos)
+ {
+ file = dir.substr(slashPos+1);
+ dir = dir.substr(0, slashPos);
+ }
+ else
+ {
+ file = dir;
+ dir = "";
+ }
+ }
+ if((dir != "") && !SystemTools::FileIsDirectory(dir.c_str()))
+ {
+ kwsys_std::string oldDir = in_name;
+ SystemTools::ConvertToUnixSlashes(oldDir);
+ dir = in_name;
+ return false;
+ }
+ return true;
+}
+
+kwsys_std::string SystemTools::CollapseFullPath(const char* in_relative)
+{
+ return SystemTools::CollapseFullPath(in_relative, 0);
+}
+
+kwsys_std::string SystemTools::CollapseFullPath(const char* in_relative,
+ const char* in_base)
+{
+ kwsys_std::string dir, file;
+ SystemTools::SplitProgramPath(in_relative, dir, file, false);
+
+ // Save original working directory.
+ kwsys_std::string orig = SystemTools::GetCurrentWorkingDirectory();
+
+ // Change to base of relative path.
+ if(in_base)
+ {
+ Chdir(in_base);
+ }
+
+#ifdef _WIN32
+ // Follow relative path.
+ if(dir != "")
+ {
+ Chdir(dir.c_str());
+ }
+
+ // Get the resulting directory.
+ kwsys_std::string newDir = SystemTools::GetCurrentWorkingDirectory();
+
+ // Add the file back on to the directory.
+ SystemTools::ConvertToUnixSlashes(newDir);
+#else
+# ifdef MAXPATHLEN
+ char resolved_name[MAXPATHLEN];
+# else
+# ifdef PATH_MAX
+ char resolved_name[PATH_MAX];
+# else
+ char resolved_name[5024];
+# endif
+# endif
+
+ // Resolve relative path.
+ kwsys_std::string newDir;
+ if(dir != "")
+ {
+ realpath(dir.c_str(), resolved_name);
+ newDir = resolved_name;
+ }
+ else
+ {
+ newDir = SystemTools::GetCurrentWorkingDirectory();
+ }
+#endif
+
+ // Restore original working directory.
+ Chdir(orig.c_str());
+
+ // Construct and return the full path.
+ kwsys_std::string newPath = newDir;
+ if(file != "")
+ {
+ newPath += "/";
+ newPath += file;
+ }
+ return newPath;
+}
+
+bool SystemTools::Split(const char* str, kwsys_std::vector<kwsys_std::string>& lines)
+{
+ kwsys_std::string data(str);
+ kwsys_std::string::size_type lpos = 0;
+ while(lpos < data.length())
+ {
+ kwsys_std::string::size_type rpos = data.find_first_of("\n", lpos);
+ if(rpos == kwsys_std::string::npos)
+ {
+ // Line ends at end of string without a newline.
+ lines.push_back(data.substr(lpos));
+ return false;
+ }
+ if((rpos > lpos) && (data[rpos-1] == '\r'))
+ {
+ // Line ends in a "\r\n" pair, remove both characters.
+ lines.push_back(data.substr(lpos, (rpos-1)-lpos));
+ }
+ else
+ {
+ // Line ends in a "\n", remove the character.
+ lines.push_back(data.substr(lpos, rpos-lpos));
+ }
+ lpos = rpos+1;
+ }
+ return true;
+}
+
+/**
+ * Return path of a full filename (no trailing slashes).
+ * Warning: returned path is converted to Unix slashes format.
+ */
+kwsys_std::string SystemTools::GetFilenamePath(const kwsys_std::string& filename)
+{
+ kwsys_std::string fn = filename;
+ SystemTools::ConvertToUnixSlashes(fn);
+
+ kwsys_std::string::size_type slash_pos = fn.rfind("/");
+ if(slash_pos != kwsys_std::string::npos)
+ {
+ return fn.substr(0, slash_pos);
+ }
+ else
+ {
+ return "";
+ }
+}
+
+
+/**
+ * Return file name of a full filename (i.e. file name without path).
+ */
+kwsys_std::string SystemTools::GetFilenameName(const kwsys_std::string& filename)
+{
+ kwsys_std::string fn = filename;
+ SystemTools::ConvertToUnixSlashes(fn);
+
+ kwsys_std::string::size_type slash_pos = fn.rfind("/");
+ if(slash_pos != kwsys_std::string::npos)
+ {
+ return fn.substr(slash_pos + 1);
+ }
+ else
+ {
+ return filename;
+ }
+}
+
+
+/**
+ * Return file extension of a full filename (dot included).
+ * Warning: this is the longest extension (for example: .tar.gz)
+ */
+kwsys_std::string SystemTools::GetFilenameExtension(const kwsys_std::string& filename)
+{
+ kwsys_std::string name = SystemTools::GetFilenameName(filename);
+ kwsys_std::string::size_type dot_pos = name.find(".");
+ if(dot_pos != kwsys_std::string::npos)
+ {
+ return name.substr(dot_pos);
+ }
+ else
+ {
+ return "";
+ }
+}
+
+
+/**
+ * Return file name without extension of a full filename (i.e. without path).
+ * Warning: it considers the longest extension (for example: .tar.gz)
+ */
+kwsys_std::string SystemTools::GetFilenameWithoutExtension(const kwsys_std::string& filename)
+{
+ kwsys_std::string name = SystemTools::GetFilenameName(filename);
+ kwsys_std::string::size_type dot_pos = name.find(".");
+ if(dot_pos != kwsys_std::string::npos)
+ {
+ return name.substr(0, dot_pos);
+ }
+ else
+ {
+ return name;
+ }
+}
+
+
+/**
+ * Return file name without extension of a full filename (i.e. without path).
+ * Warning: it considers the last extension (for example: removes .gz
+ * from .tar.gz)
+ */
+kwsys_std::string
+SystemTools::GetFilenameWithoutLastExtension(const kwsys_std::string& filename)
+{
+ kwsys_std::string name = SystemTools::GetFilenameName(filename);
+ kwsys_std::string::size_type dot_pos = name.rfind(".");
+ if(dot_pos != kwsys_std::string::npos)
+ {
+ return name.substr(0, dot_pos);
+ }
+ else
+ {
+ return name;
+ }
+}
+
+bool SystemTools::FileIsFullPath(const char* in_name)
+{
+ kwsys_std::string name = in_name;
+#if defined(_WIN32)
+ // On Windows, the name must be at least two characters long.
+ if(name.length() < 2)
+ {
+ return false;
+ }
+ if(name[1] == ':')
+ {
+ return true;
+ }
+ if(name[0] == '\\')
+ {
+ return true;
+ }
+#else
+ // On UNIX, the name must be at least one character long.
+ if(name.length() < 1)
+ {
+ return false;
+ }
+#endif
+ // On UNIX, the name must begin in a '/'.
+ // On Windows, if the name begins in a '/', then it is a full
+ // network path.
+ if(name[0] == '/')
+ {
+ return true;
+ }
+ return false;
+}
+
+void SystemTools::Glob(const char *directory, const char *regexp,
+ kwsys_std::vector<kwsys_std::string>& files)
+{
+ Directory d;
+ RegularExpression reg(regexp);
+
+ if (d.Load(directory))
+ {
+ size_t numf;
+ unsigned int i;
+ numf = d.GetNumberOfFiles();
+ for (i = 0; i < numf; i++)
+ {
+ kwsys_std::string fname = d.GetFile(i);
+ if (reg.find(fname))
+ {
+ files.push_back(fname);
+ }
+ }
+ }
+}
+
+
+void SystemTools::GlobDirs(const char *fullPath,
+ kwsys_std::vector<kwsys_std::string>& files)
+{
+ kwsys_std::string path = fullPath;
+ kwsys_std::string::size_type pos = path.find("/*");
+ if(pos == kwsys_std::string::npos)
+ {
+ files.push_back(fullPath);
+ return;
+ }
+ kwsys_std::string startPath = path.substr(0, pos);
+ kwsys_std::string finishPath = path.substr(pos+2);
+
+ Directory d;
+ if (d.Load(startPath.c_str()))
+ {
+ for (unsigned int i = 0; i < d.GetNumberOfFiles(); ++i)
+ {
+ if((kwsys_std::string(d.GetFile(i)) != ".")
+ && (kwsys_std::string(d.GetFile(i)) != ".."))
+ {
+ kwsys_std::string fname = startPath;
+ fname +="/";
+ fname += d.GetFile(i);
+ if(SystemTools::FileIsDirectory(fname.c_str()))
+ {
+ fname += finishPath;
+ SystemTools::GlobDirs(fname.c_str(), files);
+ }
+ }
+ }
+ }
+}
+
+bool SystemTools::GetShortPath(const char* path, kwsys_std::string& shortPath)
+{
+#if defined(WIN32) && !defined(__CYGWIN__)
+ const int size = int(strlen(path)) +1; // size of return
+ char *buffer = new char[size]; // create a buffer
+ char *tempPath = new char[size]; // create a buffer
+ int ret;
+
+ // if the path passed in has quotes around it, first remove the quotes
+ if (path[0] == '"' && path[strlen(path)-1] == '"')
+ {
+ strcpy(tempPath,path+1);
+ tempPath[strlen(tempPath)-1] = '\0';
+ }
+ else
+ {
+ strcpy(tempPath,path);
+ }
+
+ buffer[0] = 0;
+ ret = GetShortPathName(tempPath, buffer, size);
+
+ if(buffer[0] == 0 || ret > size)
+ {
+ delete [] buffer;
+ delete [] tempPath;
+ return false;
+ }
+ else
+ {
+ shortPath = buffer;
+ delete [] buffer;
+ delete [] tempPath;
+ return true;
+ }
+#else
+ shortPath = path;
+ return true;
+#endif
+}
+
+bool SystemTools::SimpleGlob(const kwsys_std::string& glob,
+ kwsys_std::vector<kwsys_std::string>& files,
+ int type /* = 0 */)
+{
+ files.clear();
+ if ( glob[glob.size()-1] != '*' )
+ {
+ return false;
+ }
+ kwsys_std::string path = SystemTools::GetFilenamePath(glob);
+ kwsys_std::string ppath = SystemTools::GetFilenameName(glob);
+ ppath = ppath.substr(0, ppath.size()-1);
+ if ( path.size() == 0 )
+ {
+ path = "/";
+ }
+
+ bool res = false;
+ Directory d;
+ if (d.Load(path.c_str()))
+ {
+ for (unsigned int i = 0; i < d.GetNumberOfFiles(); ++i)
+ {
+ if((kwsys_std::string(d.GetFile(i)) != ".")
+ && (kwsys_std::string(d.GetFile(i)) != ".."))
+ {
+ kwsys_std::string fname = path;
+ if ( path[path.size()-1] != '/' )
+ {
+ fname +="/";
+ }
+ fname += d.GetFile(i);
+ kwsys_std::string sfname = d.GetFile(i);
+ if ( type > 0 && SystemTools::FileIsDirectory(fname.c_str()) )
+ {
+ continue;
+ }
+ if ( type < 0 && !SystemTools::FileIsDirectory(fname.c_str()) )
+ {
+ continue;
+ }
+ if ( sfname.size() >= ppath.size() &&
+ sfname.substr(0, ppath.size()) ==
+ ppath )
+ {
+ files.push_back(fname);
+ res = true;
+ }
+ }
+ }
+ }
+ return res;
+}
+
+
+void SystemTools::SplitProgramFromArgs(const char* path,
+ kwsys_std::string& program, kwsys_std::string& args)
+{
+ if(SystemTools::FileExists(path))
+ {
+ program = path;
+ args = "";
+ return;
+ }
+ kwsys_std::vector<kwsys_std::string> e;
+ kwsys_std::string findProg = SystemTools::FindProgram(path, e);
+ if(findProg.size())
+ {
+ program = findProg;
+ args = "";
+ return;
+ }
+ kwsys_std::string dir = path;
+ kwsys_std::string::size_type spacePos = dir.rfind(' ');
+ if(spacePos == kwsys_std::string::npos)
+ {
+ program = "";
+ args = "";
+ return;
+ }
+ while(spacePos != kwsys_std::string::npos)
+ {
+ kwsys_std::string tryProg = dir.substr(0, spacePos);
+ if(SystemTools::FileExists(tryProg.c_str()))
+ {
+ program = tryProg;
+ args = dir.substr(spacePos, dir.size()-spacePos);
+ return;
+ }
+ findProg = SystemTools::FindProgram(tryProg.c_str(), e);
+ if(findProg.size())
+ {
+ program = findProg;
+ args = dir.substr(spacePos, dir.size()-spacePos);
+ return;
+ }
+ spacePos = dir.rfind(' ', spacePos--);
+ }
+ program = "";
+ args = "";
+}
+
+kwsys_std::string SystemTools::GetCurrentDateTime(const char* format)
+{
+ char buf[1024];
+ time_t t;
+ time(&t);
+ strftime(buf, sizeof(buf), format, localtime(&t));
+ return buf;
+}
+
+kwsys_std::string SystemTools::MakeCindentifier(const char* s)
+{
+ kwsys_std::string str(s);
+ if (str.find_first_of("0123456789") == 0)
+ {
+ str = "_" + str;
+ }
+
+ kwsys_std::string permited_chars("_"
+ "abcdefghijklmnopqrstuvwxyz"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "0123456789");
+ kwsys_std::string::size_type pos = 0;
+ while ((pos = str.find_first_not_of(permited_chars, pos)) != kwsys_std::string::npos)
+ {
+ str[pos] = '_';
+ }
+ return str;
+}
+
+// Due to a buggy stream library on the HP and another on Mac OSX, we
+// need this very carefully written version of getline. Returns true
+// if any data were read before the end-of-file was reached.
+bool SystemTools::GetLineFromStream(kwsys_std::istream& is, kwsys_std::string& line)
+{
+ const int bufferSize = 1024;
+ char buffer[bufferSize];
+ line = "";
+ bool haveData = false;
+
+ // If no characters are read from the stream, the end of file has
+ // been reached.
+ while((is.getline(buffer, bufferSize), is.gcount() > 0))
+ {
+ haveData = true;
+ line.append(buffer);
+
+ // If newline character was read, the gcount includes the
+ // character, but the buffer does not. The end of line has been
+ // reached.
+ if(strlen(buffer) < static_cast<size_t>(is.gcount()))
+ {
+ break;
+ }
+
+ // The fail bit may be set. Clear it.
+ is.clear(is.rdstate() & ~kwsys_std::ios::failbit);
+ }
+ return haveData;
+}
+
+#if defined(_MSC_VER) && defined(_DEBUG)
+# include <crtdbg.h>
+# include <stdio.h>
+# include <stdlib.h>
+static int SystemToolsDebugReport(int, char* message, int*)
+{
+ fprintf(stderr, message);
+ exit(1);
+ return 0;
+}
+void SystemTools::EnableMSVCDebugHook()
+{
+ if(getenv("DART_TEST_FROM_DART"))
+ {
+ _CrtSetReportHook(SystemToolsDebugReport);
+ }
+}
+#else
+void SystemTools::EnableMSVCDebugHook()
+{
+}
+#endif
+
+} // namespace KWSYS_NAMESPACE