summaryrefslogtreecommitdiff
path: root/cpp/src/Slice/Util.cpp
diff options
context:
space:
mode:
authorBenoit Foucher <benoit@zeroc.com>2008-04-21 17:58:38 +0200
committerBenoit Foucher <benoit@zeroc.com>2008-04-21 17:58:38 +0200
commit094286e06f0ff154f20fcccce0c71068a3d216d5 (patch)
tree606797928608baa057fe9a9ea096622e0eb37930 /cpp/src/Slice/Util.cpp
parentFixed potential IceUtil::NullHandleException (diff)
downloadice-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.cpp147
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;
}
+