diff options
author | Benoit Foucher <benoit@zeroc.com> | 2008-04-21 17:58:38 +0200 |
---|---|---|
committer | Benoit Foucher <benoit@zeroc.com> | 2008-04-21 17:58:38 +0200 |
commit | 094286e06f0ff154f20fcccce0c71068a3d216d5 (patch) | |
tree | 606797928608baa057fe9a9ea096622e0eb37930 /cpp/src/Slice/Util.cpp | |
parent | Fixed potential IceUtil::NullHandleException (diff) | |
download | ice-094286e06f0ff154f20fcccce0c71068a3d216d5.tar.bz2 ice-094286e06f0ff154f20fcccce0c71068a3d216d5.tar.xz ice-094286e06f0ff154f20fcccce0c71068a3d216d5.zip |
Fixed bug 3011
Diffstat (limited to 'cpp/src/Slice/Util.cpp')
-rw-r--r-- | cpp/src/Slice/Util.cpp | 147 |
1 files changed, 107 insertions, 40 deletions
diff --git a/cpp/src/Slice/Util.cpp b/cpp/src/Slice/Util.cpp index c4cb197e655..4d6be4e1834 100644 --- a/cpp/src/Slice/Util.cpp +++ b/cpp/src/Slice/Util.cpp @@ -11,9 +11,7 @@ #include <IceUtil/Unicode.h> #include <climits> -#ifdef __hpux -# include <unistd.h> -#endif +#include <unistd.h> // For readlink() #ifdef __BCPLUSPLUS__ # include <dir.h> @@ -22,74 +20,143 @@ using namespace std; using namespace Slice; -string -Slice::getCwd() +static string +normalizePath(const string& path) { -#ifdef _WIN32 - wchar_t cwdbuf[_MAX_PATH]; - if(_wgetcwd(cwdbuf, _MAX_PATH) != NULL) + string result = path; + replace(result.begin(), result.end(), '\\', '/'); + string::size_type pos; + while((pos = result.find("//")) != string::npos) { - return IceUtil::wstringToString(cwdbuf); + result.replace(pos, 2, "/"); } -#else - char cwdbuf[PATH_MAX]; - if(::getcwd(cwdbuf, PATH_MAX) != NULL) + pos = 0; + while((pos = result.find("/./", pos)) != string::npos) { - return cwdbuf; + result.erase(pos, 2); } -#endif - return ""; + pos = 0; + while((pos = result.find("/..", pos)) != string::npos) + { + string::size_type last = result.find_last_of("/", pos - 1); + if(last != string::npos && result.substr(last, 4) != "/../") + { + result.erase(last, pos - last + 3); + pos = last; + } + else + { + ++pos; + } + } + if(result[result.size() - 1] == '/') // Remove trailing '/' + { + result.erase(result.size() - 1); + } + return result; } bool Slice::isAbsolute(const string& path) { #ifdef _WIN32 - if(path[0] == '\\' || path[0] == '/' || path.size() > 1 && isalpha(path[0]) && path[1] == ':') + if(path[0] == '\\' || path[0] == '/' || path.size() > 1 && isalpha(path[0]) && path[1] == ':') #else - if(path[0] == '/') + if(path[0] == '/') #endif - { - return true; - } - - return false; + { + return true; + } + return false; } string -Slice::normalizePath(const string& path, bool removeDriveLetter) +Slice::fullPath(const string& path) { - string result = path; - replace(result.begin(), result.end(), '\\', '/'); - string::size_type pos; - while((pos = result.find("//")) != string::npos) +#ifdef _WIN32 + if(!isAbsolute(path)) { - result.replace(pos, 2, "/"); + wchar_t cwdbuf[_MAX_PATH]; + if(_wgetcwd(cwdbuf, _MAX_PATH) != NULL) + { + return normalizePath(IceUtil::wstringToString(cwdbuf) + "/" + path); + } } - pos = 0; - while((pos = result.find("/./", pos)) != string::npos) + return normalizePath(path); +#else + string result = path; + if(!isAbsolute(result)) { - result.erase(pos, 2); + char cwdbuf[PATH_MAX]; + if(::getcwd(cwdbuf, PATH_MAX) != NULL) + { + result = string(cwdbuf) + '/' + result; + } } - pos = 0; - while((pos = result.find("/..", pos)) != string::npos) + result = normalizePath(result); + + string::size_type beg = 0; + string::size_type next; + do { - string::size_type last = result.find_last_of("/", pos - 1); - if(last != string::npos && result.substr(last, 4) != "/../") + string subpath; + next = result.find('/', beg + 1); + if(next == string::npos) { - result.erase(last, pos - last + 3); - pos = last; + subpath = result; } else { - ++pos; + subpath = result.substr(0, next); + } + + char buf[PATH_MAX + 1]; + int len = readlink(subpath.c_str(), buf, sizeof(buf)); + if(len > 0) + { + buf[len] = '\0'; + result = normalizePath(buf) + (next != string::npos ? result.substr(next) : string()); + beg = 0; + next = 0; + } + else + { + beg = next; } } + while(next != string::npos); + return result; +#endif +} - if(removeDriveLetter && result.size() > 1 && isalpha(result[0]) && result[1] == ':') +string +Slice::changeInclude(const string& orig, const vector<string>& includePaths) +{ + string file = fullPath(orig); + + // + // Compare each include path against the included file and select + // the path that produces the shortest relative filename. + // + string result = file; + for(vector<string>::const_iterator p = includePaths.begin(); p != includePaths.end(); ++p) { - result = result.substr(2); + if(file.compare(0, p->length(), *p) == 0) + { + string s = file.substr(p->length() + 1); // + 1 for the '/' + if(s.size() < result.size()) + { + result = s; + } + } + } + + string::size_type pos; + if((pos = result.rfind('.')) != string::npos) + { + result.erase(pos); } return result; } + |