From 23276ca3a29a4a6a79b54d77a1ec5bfd8f0f381a Mon Sep 17 00:00:00 2001 From: Brad King Date: Thu, 10 Feb 2005 14:19:06 -0500 Subject: [PATCH] ENH: Initializing translation map using the PWD environment variable and getcwd functions to automatically translate logical paths involving the current working directory. Also added the JoinPath method to aid users of the SplitPath method. --- Source/kwsys/SystemTools.cxx | 93 ++++++++++++++++++++++++++------- Source/kwsys/SystemTools.hxx.in | 9 +++- 2 files changed, 82 insertions(+), 20 deletions(-) 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&);