diff options
author | Benoit Foucher <benoit@zeroc.com> | 2015-01-26 16:34:02 +0100 |
---|---|---|
committer | Benoit Foucher <benoit@zeroc.com> | 2015-01-26 16:34:02 +0100 |
commit | 9030e89de3dc908c6071e7614f4e8b2ab3e1d5e0 (patch) | |
tree | a9b09abe53ecf256c987695c51b0f5be288b1637 /cpp/src/Slice/Util.cpp | |
parent | ICE-6284 ObjC: add IceDiscovery demo (diff) | |
download | ice-9030e89de3dc908c6071e7614f4e8b2ab3e1d5e0.tar.bz2 ice-9030e89de3dc908c6071e7614f4e8b2ab3e1d5e0.tar.xz ice-9030e89de3dc908c6071e7614f4e8b2ab3e1d5e0.zip |
Fixed ICE-5833: bogus absolute paths generated in headers
Diffstat (limited to 'cpp/src/Slice/Util.cpp')
-rw-r--r-- | cpp/src/Slice/Util.cpp | 94 |
1 files changed, 71 insertions, 23 deletions
diff --git a/cpp/src/Slice/Util.cpp b/cpp/src/Slice/Util.cpp index c6b847713d4..5be8bbde126 100644 --- a/cpp/src/Slice/Util.cpp +++ b/cpp/src/Slice/Util.cpp @@ -10,12 +10,20 @@ #include <Slice/Util.h> #include <IceUtil/FileUtil.h> #include <IceUtil/StringUtil.h> +#include <climits> + +#ifndef _MSC_VER +# include <unistd.h> // For readlink() +#endif using namespace std; using namespace Slice; +namespace +{ + string -Slice::normalizePath(const string& path) +normalizePath(const string& path) { string result = path; @@ -71,9 +79,23 @@ Slice::normalizePath(const string& path) return result; } +} + string Slice::fullPath(const string& path) { + // + // This function returns the canonicalized absolute pathname of + // the given path. + // + // It is used for instance used to normalize the paths provided + // with -I options. Like mcpp, we need to follow the symbolic + // links to ensure changeIncludes works correctly. For example, it + // must be possible to specify -I/opt/Ice-3.6 where Ice-3.6 is + // symbolic link to Ice-3.6.0 (if we don't do the same as mcpp, + // the generated headers will contain a full path...) + // + string result = path; if(!IceUtilInternal::isAbsolutePath(result)) { @@ -84,24 +106,56 @@ Slice::fullPath(const string& path) } } - return normalizePath(result); -} + result = normalizePath(result); -string -Slice::changeInclude(const string& orig, const vector<string>& includePaths) -{ - // - // MCPP does not follow symlinks included files so we only - // call fullPath on the base directory and not the file itself. - // - string file = orig; - string::size_type pos; - if((pos = orig.rfind('/')) != string::npos) +#ifdef _WIN32 + return result; +#else + + string::size_type beg = 0; + string::size_type next; + do { - string base = orig.substr(0, pos); - file = fullPath(base) + orig.substr(pos); + string subpath; + next = result.find('/', beg + 1); + if(next == string::npos) + { + subpath = result; + } + else + { + subpath = result.substr(0, next); + } + + char buf[PATH_MAX + 1]; + int len = static_cast<int>(readlink(subpath.c_str(), buf, sizeof(buf))); + if(len > 0) + { + buf[len] = '\0'; + string linkpath = buf; + if(!IceUtilInternal::isAbsolutePath(linkpath)) // Path relative to the location of the link + { + string::size_type pos = subpath.rfind('/'); + assert(pos != string::npos); + linkpath = subpath.substr(0, pos + 1) + linkpath; + } + result = normalizePath(linkpath) + (next != string::npos ? result.substr(next) : string()); + beg = 0; + next = 0; + } + else + { + beg = next; + } } + while(next != string::npos); + return result; +#endif +} +string +Slice::changeInclude(const string& file, const vector<string>& includePaths) +{ // // Compare each include path against the included file and select // the path that produces the shortest relative filename. @@ -119,15 +173,9 @@ Slice::changeInclude(const string& orig, const vector<string>& includePaths) } } - if(result == file) - { - // - // Don't return a full path if we couldn't reduce the given path, instead - // return the normalized given path. - // - result = normalizePath(orig); - } + result = normalizePath(result); // Normalize the result. + string::size_type pos; if((pos = result.rfind('.')) != string::npos) { result.erase(pos); |