diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx index ecd6fe8b6..023eae883 100644 --- a/Source/kwsys/SystemTools.cxx +++ b/Source/kwsys/SystemTools.cxx @@ -1541,8 +1541,6 @@ void SystemTools::CheckTranslationPath(kwsys_stl::string & path) kwsys_stl::string SystemTools::CollapseFullPath(const char* in_relative, const char* in_base) { - static int initialized = 0; - kwsys_stl::string orig; // Change to base of relative path. @@ -1590,23 +1588,6 @@ kwsys_stl::string SystemTools::CollapseFullPath(const char* in_relative, newPath += file; } - // If the table has never been initialized, add default path: - if(!initialized) - { - initialized = 1; - // add some special translation paths for unix - // these are not added for windows because drive - // letters need to be maintained. Also, there - // are not sym-links and mount points on windows anyway. -#if !defined( _WIN32 ) - //Also add some good default one: - // This one should always be there it fix a bug on sgi - SystemTools::AddTranslationPath("/tmp_mnt/", "/"); - //This is a good default also: - SystemTools::AddKeepPath("/tmp/"); -#endif - } - // Now we need to update the translation table with this potentially new path SystemTools::AddTranslationPath(newPath.c_str(), in_relative); SystemTools::CheckTranslationPath(newPath); @@ -1674,6 +1655,27 @@ void SystemTools::SplitPath(const char* p, } } +//---------------------------------------------------------------------------- +kwsys_stl::string +SystemTools::JoinPath(const kwsys_stl::vector& components) +{ + kwsys_stl::string result; + if(components.size() > 0) + { + result += components[0]; + } + if(components.size() > 1) + { + result += components[1]; + } + for(unsigned int i=2; i < components.size(); ++i) + { + result += "/"; + result += components[i]; + } + return result; +} + bool SystemTools::Split(const char* str, kwsys_stl::vector& lines) { kwsys_stl::string data(str); @@ -2198,7 +2200,60 @@ SystemToolsManager::~SystemToolsManager() void SystemTools::ClassInitialize() { + // Allocate the translation map first. SystemTools::TranslationMap = new SystemToolsTranslationMap; + + // Add some special translation paths for unix. These are not added + // for windows because drive letters need to be maintained. Also, + // there are not sym-links and mount points on windows anyway. +#if !defined(_WIN32) || defined(__CYGWIN__) + // Work-around an SGI problem by always adding this mapping: + SystemTools::AddTranslationPath("/tmp_mnt/", "/"); + // The tmp path is frequently a logical path so always keep it: + SystemTools::AddKeepPath("/tmp/"); + + // If the current working directory is a logical path then keep the + // logical name. + if(const char* pwd = getenv("PWD")) + { + char buf[2048]; + if(const char* cwd = Getcwd(buf, 2048)) + { + kwsys_stl::string pwd_path; + Realpath(pwd, pwd_path); + if(cwd == pwd_path && strcmp(cwd, pwd) != 0) + { + // The current working directory is a logical path. Split + // both the logical and physical paths into their components. + kwsys_stl::vector cwd_components; + kwsys_stl::vector pwd_components; + SystemTools::SplitPath(cwd, cwd_components); + SystemTools::SplitPath(pwd, pwd_components); + + // Remove the common ending of the paths to leave only the + // part that changes under the logical mapping. + kwsys_stl::vector::iterator ic = cwd_components.end(); + kwsys_stl::vector::iterator ip = pwd_components.end(); + for(;ip != pwd_components.begin() && ic != cwd_components.begin() && + *(ip-1) == *(ic-1); --ip,--ic); + cwd_components.erase(ic, cwd_components.end()); + pwd_components.erase(ip, pwd_components.end()); + + // Reconstruct the string versions of the part of the path + // that changed. + kwsys_stl::string cwd_changed = SystemTools::JoinPath(cwd_components); + kwsys_stl::string pwd_changed = SystemTools::JoinPath(pwd_components); + + // Add the translation to keep the logical path name. + if(!cwd_changed.empty() && !pwd_changed.empty()) + { + SystemTools::AddTranslationPath(cwd_changed.c_str(), + pwd_changed.c_str()); + } + } + } + } +#endif } void SystemTools::ClassFinalize() diff --git a/Source/kwsys/SystemTools.hxx.in b/Source/kwsys/SystemTools.hxx.in index e65ee05e1..4e042ffa0 100644 --- a/Source/kwsys/SystemTools.hxx.in +++ b/Source/kwsys/SystemTools.hxx.in @@ -254,7 +254,14 @@ public: */ static void SplitPath(const char* p, kwsys_stl::vector& components); - + + /** + * Join components of a path name into a single string. See + * SplitPath for the format of the components. + */ + static kwsys_stl::string + JoinPath(const kwsys_stl::vector& components); + ///! return path of a full filename (no trailing slashes). static kwsys_stl::string GetFilenamePath(const kwsys_stl::string&);